4

I have a table consisting of key/value pairs:

mytable[a] = 1, 
mytable[b] = 4, 
mytable[r] = 7, 
mytable[f] = 2,

etc.

I want to sort the table by the numbers. So I'd like the table to be {(a, 1), (f, 2), (b, 4), (r, 7)} I've tried using

table.sort(mytable, function(a, b) return a[2] > b[2] end)

but that didn't seem to work... Thankyou

Jake
  • 97
  • 1
  • 6
  • 1
    tables in Lua don't have any order, so you can't sort them. Only sequences have an implicit order through their numeric indices, but that's a matter of interpretation, unrelated to the table itself. – DarkWiiPlayer Oct 11 '19 at 09:45

2 Answers2

5

One way that is suggested in "Programming Lua" (I don't remember where exactly) is to extract the keys into a separate sequence, then sort the sequence, and use the resulting sorted sequence to index into the original table. Example:

keys = {}

for key, _ in pairs(mytable) do
    table.insert(keys, key)
end

table.sort(keys, function(keyLhs, keyRhs) return mytable[keyLhs] < mytable[keyRhs] end)

You can then iterate over the keys to retrieve the corresponding values:

for _, key in ipairs(keys) do
    print(key, mytable[key])
end
lubgr
  • 37,368
  • 3
  • 66
  • 117
3

A table either is a set of key/value pairs or an array. OK, that's not entirely true; a table can be both, but the key/value entries will have no relationship to the array entries. That is, you can do this:

tbl = {
  ['a'] = 1,
  ['b'] = 4,
  [1] = {'a', 1},
  [2] = {'b', 4},
}

tbl[2] will have no direct relationship to tbl['b']. You can perform tbl[2] = <anything>, and it will have no effect on the contents of tbl['b'].

So long as the table doesn't change, you can take any pure key/value table and build an array part of it, which you can then sort however you like. Here's a function which does that:

local function build_array(tbl)
  --We cannot modify `tbl` while iterating through it, so build a temp array.
  local arr = {}
  for key, value in pairs(tbl) do
    arr[#arr + 1] = {key, value}
  end

  for ix, value in ipairs(arr) do
    tbl[ix] = value
  end

  return tbl
end
Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • May you add to your answer for the sake of completeness also the code which uses the provided `build_array(tbl)` function and returns by value sorted original table `tbl`? Do I understand it right that Lua guarantees always the same order of the table pairs returned by `pairs()`? Or is it necessary to wrap a table by an array-like table to get a guaranteed order of the items determined by the order of the natural numbers in range `1..sizeOfTable` used as keys for ordered delivery of table items? – Claudio Aug 18 '23 at 06:54