Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

How to sort a table on 2 values?
Started by ivke2006 Apr 11 2014 01:38 AM

- - - - -
6 replies to this topic
[TOPIC CONTROLS]
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

ivke2006

[GLOBAL: userInfoPane.html]
ivke2006
  • Starter
  • PipPipPipPipPipPip
  • 71 posts
  • Jedi

Hi,

 

I'm trying to sort a table alphabetically on 2 values, but so far no luck.

 

The table should be sorted on category and within a certain category range the name field should also be sorted.

So all category "bread" should be on top and within this category all name values should also be sorted alphabetically. 

 

local food =    { 
                {category = "Bread", name = "white"},
                {category = "drinks", name = "cola"},
                {category = "Bread", name = "corn"},
                {category = "Bread", name = "french"},
                {category = "drinks", name = "milk"},
                {category = "drinks", name = "soda"}

                }

 

via :

local function tableSortCat (a,b)
  return a.category < b.category
end

table.sort( foodlist, tableSortCat)

 

I'm able to sort on category only but not both.

Can anyone help me to solve this?

 

Thanks!

 



[TOPIC: post.html]
#2

Icy Spark

[GLOBAL: userInfoPane.html]
Icy Spark
  • Pro
  • PipPipPipPipPipPip
  • 243 posts
  • Jedi

Here you go.  Tested and working.

 

local food =    { 
                {category = "Bread", name = "white"},
                {category = "drinks", name = "cola"},
                {category = "Bread", name = "corn"},
                {category = "Bread", name = "french"},
                {category = "drinks", name = "soda"},
                {category = "drinks", name = "milk"}
                }
   
local function tableSortCat (a, b )
    if (a.category < b.category) then
           return true
        elseif (a.category > b.category) then
            return false
        else
              return a.name < b.name
        end
end
 
table.sort( food, tableSortCat)       
                
for i=1,#food do
    print (food[i].category,food[i].name)
end                



[TOPIC: post.html]
#3

horacebury

[GLOBAL: userInfoPane.html]
horacebury
  • Pro
  • PipPipPipPipPipPip
  • 2,003 posts
  • Jedi

I think you could collapse the sort function to this:

local function tableSortCat (a, b )
    return (a.category < b.category) or (a.category == b.category and a.name < b.name)
end

I've not tested this.



[TOPIC: post.html]
#4

ivke2006

[GLOBAL: userInfoPane.html]
ivke2006
  • Starter
  • PipPipPipPipPipPip
  • 71 posts
  • Jedi

Wow! Already some replies.   :)

 

@ Icy Spark:

 

It works!!

 

but..

 

I'm not able to understand what is happening in your sort function.

 

Could you maybe explain a little bit?

 

Many Thanks!!

 

@ horacebury: 

 

Thanks for your reply. In your sort function the category are correctly sorted but the names not.



[TOPIC: post.html]
#5

horacebury

[GLOBAL: userInfoPane.html]
horacebury
  • Pro
  • PipPipPipPipPipPip
  • 2,003 posts
  • Jedi

With this code:

local food = {
	{category = "Bread", name = "white"},
	{category = "drinks", name = "cola"},
	{category = "Bread", name = "corn"},
	{category = "Bread", name = "french"},
	{category = "drinks", name = "milk"},
	{category = "drinks", name = "soda"}
}

local function tableSortCat( a, b )
	return (a.category < b.category) or (a.category == b.category and a.name < b.name)
end

table.sort( food, tableSortCat )

for i=1, #food do
	print(food[i].category, food[i].name)
end

I get this result:

Bread   corn
Bread   french
Bread   white
drinks  cola
drinks  milk
drinks  soda

Which looks right to me. The categories are sorted in alphabetical order and under the categories then individual foods are alphabetical.

 

What are you looking for?



[TOPIC: post.html]
#6

Icy Spark

[GLOBAL: userInfoPane.html]
Icy Spark
  • Pro
  • PipPipPipPipPipPip
  • 243 posts
  • Jedi

Hi Horace,  I haven't checked your code but the drinks names seem to be in order because they are already in order as you have added them to your initial table?

 

Hence the reason I moved soda above milk for my test.

 

Give it a whirl when the drinks names are not in order.



[TOPIC: post.html]
#7

horacebury

[GLOBAL: userInfoPane.html]
horacebury
  • Pro
  • PipPipPipPipPipPip
  • 2,003 posts
  • Jedi

Yes, the drinks are already in order, but the foods are not and they get sorted just fine. I unordered the drinks just to check and they also get sorted properly:

 

local food = {
	{category = "Bread", name = "white"},
	{category = "drinks", name = "milk"},
	{category = "Bread", name = "corn"},
	{category = "Bread", name = "french"},
	{category = "drinks", name = "cola"},
	{category = "drinks", name = "soda"}
}

local function tableSortCat( a, b )
	return (a.category < b.category) or (a.category == b.category and a.name < b.name)
end

table.sort( food, tableSortCat )

for i=1, #food do
	print(food[i].category, food[i].name)
end

Sorted to:

Bread   corn
Bread   french
Bread   white
drinks  cola
drinks  milk
drinks  soda

So I believe that my solution works.

 

All I did in the function is to compress the logic of the multiple if statements in Icy Spark's logic. This took a bit of double-checking because the short-circuiting nature of if statements can lead coders to miss things, but I think I got it in the end. It's a good mental exercise to go through.




[topic_controls]
[/topic_controls]