1

So, as the title says, I would like to sort a table of tables in Lua. One such example nested table is below.

tabl = {2.0={amount=281.0, meta=0.0, displayName=Dirt, name=minecraft:dirt}, 3.0={amount=190103.0, meta=0.0, displayName=Cobblestone, name=minecraft:cobblestone}, ...}

I would like to go through and return a table of the top ten tabl[*]['amount'] listed with their respective tabl[*]['displayName'] * being a wildcard for tabl[1.0] through tabl[max.0]

A finished table should look something like:

sorted = {1={displayName=Cobblestone, amount=190103}, 2={displayName=Dirt, amount=281}, ...}

I hope this makes sense to all out there.

Link to full nested table: Full Piece FYI: I am not in control of how the table is returned to me; I got them from the function listItems() in this API.

  • You need to put numbers in [ ] to have correct syntax. sorted = { [1]={displayName=Cobblestone, amount=190103}, [2]={displayName=Dirt, amount=281} } Even though natural number indices are the default, but just in case you need to specify elements in a different order. – tonypdmtr Apr 02 '16 at 08:34

2 Answers2

3

First of all, your arrays aren't syntactically correct. It should be more like:

local people = {
    {Name="Alice",Score=10},
    {Name="Bob",Score=3},
    {Name="Charlie",Score=17}
}

Secondly, the table.sort function should do the job. In my particular example it would look like this:

table.sort(people, function(a,b) return a.Score > b.Score end)

And finally, to get the top N just iterate:

for i = 1,N do
    print(people[i].Name, people[i].Score)
end
warspyking
  • 3,045
  • 4
  • 20
  • 37
  • 1
    a comma is missing in line 3. also you should make sure that N does not exceed #people. Otherwise you"ll get an error for indexing nil values. – Piglet Apr 02 '16 at 13:18
  • @Piglet Fixed comma, N exceeding #people would be a mistake on his end, I simply explained how to do it. – warspyking Apr 02 '16 at 13:30
  • 1
    @warspyking But it could be corrected like so: for i = 1,N <= #people and N or #people do – tonypdmtr Apr 02 '16 at 14:33
  • @tony While true, he should never run into the problem in the first place. Why run extra code, for the price of inefficiency? – warspyking Apr 02 '16 at 15:41
  • @warspyking I'm sorry I should have mentioned that I have no control over the original piece, it is returned by an external api. – Herobrine2Nether Apr 02 '16 at 16:49
0

So, I worked at it for a while, and thanks to community answers I came up with this piece:

bridge = peripheral.wrap("left")
items = bridge.listItems()

sorted = {}

for i, last in next, items do
  sorted[i] = {}
  sorted[i]["displayName"] = items[i]["displayName"]
  sorted[i]["amount"] = items[i]["amount"]
end

table.sort(sorted, function(a,b) return a.amount > b.amount end)

for i = 1, 10 do
  print(i .. ": " .. sorted[i].displayName .. ": " .. sorted[i].amount)
end

It returned the top 10 inventories:

1: Cobblestone: 202924
2: Gunpowder: 1382
3: Flint: 1375
4: Oak Sapling: 1099
5: Arrow: 966
6: Bone Meal: 946
7: Sky Stone Dust: 808
8: Certus Quartz Dust: 726
9: Rotten Flesh: 627
10: Coal: 618