In Lua, pairs
and ipairs
can iterate over the same elements in a different order:
> t = {[1]=1, [2]=2, [3]=3}
> for k,v in pairs(t) do print(k,v) end
2 2
1 1
3 3
> for k,v in ipairs(t) do print(k,v) end
1 1
2 2
3 3
When using the C API, I see only one tool for iterating over a table: the lua_next() function which acts very much like the pairs()
Lua function which produces the 2-1-3 order shown above.
I am looking for an efficient C method for iterating over the integer keys of a table sequentially(a C API version of ipairs).
Naively, I considered:
int tableLength = luaL_len(L, tableIndex);
for (i=0, i++, i>tableLength){
// if t[i] is not null ...
}
but I am unclear of potential performance issues where table sizes do not match the number of consecutive integer keys:
t = {[1]=1, [2]=2, [4]=4} -- has a (reported) length of 4
t = {[1]=1, [2]=2, [40000]=4} -- has a (reported) length of 2
If this is indeed the way ipairs does it, then is there an easy way to start using lua_next with the last found integer key to continue to walk the rest of the table avoiding walking the integer-key portion again? Is there a chance I will see some integer keys twice by doing so?
t = {[1]=1, [2]=2, [4]=4} -- has a length of 4
Well there's your problem right there; that does not have a length of 4. You might think it does, and #t
might return 4. But as far as the Lua API is concerned, the length of this table is undefined.
Lua 5.1 states:
The length of a table t is defined to be any integer index n such that t[n] is not nil and t[n+1] is nil; moreover, if t1 is nil, n can be zero. For a regular array, with non-nil values from 1 to a given n, its length is exactly that n, the index of its last value. If the array has "holes" (that is, nil values between other non-nil values), then #t can be any of the indices that directly precedes a nil value (that is, it may consider any such nil value as the end of the array).
Lua 5.2 is rather more explicit:
the length of a table t is only defined if the table is a sequence, that is, the set of its positive numeric keys is equal to {1..n} for some integer n. In that case, n is its length. Note that a table like
{10, 20, nil, 40}
is not a sequence, because it has the key 4 but does not have the key 3. (So, there is no n such that the set {1..n} is equal to the set of positive numeric keys of that table.) Note, however, that non-numeric keys do not interfere with whether a table is a sequence.
But in both cases, the length is undefined.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With