aster94
aster94

Reputation: 357

lua string-indexed table and unpack

I have a table in lua populated by items with string index. It is known, unfortunately, that lua doesn't handle this in a perfect (headache-free) way because the # operator and table.unpack() won't work

t = {}
t['b'] = 2
t['a'] = 1

print("l:", #t)
print("t:", table.unpack(t))

returns:

l:  0
t:

There are solution to count the items (i.e: counting string-indexed tables in lua) but i wasn't able to find a replacement for the table.unpack() someone can give an hand?

The desired output is: 2 1 (in the same order as I added them)

Upvotes: 5

Views: 2575

Answers (1)

Nicol Bolas
Nicol Bolas

Reputation: 473272

Lua tables store non-array elements in an arbitrary order. And unpacking is worthless without some control over the order of the generated elements. So it's not possible to usefully unpack the non-array portion of a table.

Now, you can still do it; you just won't have any kind of control over the order. So it's not clear what the point would be, but the code would look like this:

function unpack_unordered_recursive(tbl, key)
  local new_key, value = next(tbl, key)
  if new_key == nil then return end

  return value, unpack_unordered_recursive(tbl, new_key)
end

function unpack_unordered(tbl)
  local key, value = next(tbl)
  if key == nil then return end

  return value, unpack_unordered_recursive(tbl, key)
end

However, if you have an array table that contains the list of keys to extract and the order to extract them in, then you can write an unpack function that uses such a table:

function unpack_indices(tbl, indices, curr_ix)
  if curr_ix == nil then
    return unpack_indices(tbl, indices, 1)
  end

  if curr_ix > #indices then
    return
  end

  --Recursive call
  return tbl[indices[curr_ix]], unpack_indices(tbl, indices, curr_ix + 1)
end

print("t:", unpack_indices(t, {"b", "a"}))

Upvotes: 4

Related Questions