lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Fri, Aug 15, 2014 at 3:35 PM, Jay Carlson <nop@nop.com> wrote:
> What do useful non-array iterators, say, non_ipairs() and non_inext() look like?


first of all: as you said, "array part" and "hash part" are
implementation details and there are no guarantees about which keys
would fall on either part.  ipairs() isn't defined as "iterates the
array part", #t isn't defined as "the last index in the array part";
both will happily enter the hash if appropriate.

therefore, a non-implementation-specific specification of "non-ipairs"
would likely be something like "every key,value pair except for
integers between 1 and #t".  as such, i guess the only implementation
that doesn't peek into Lua internals would be your 1) case; boringly
skipping those integers.

but, if you read the Lua source for the next() function, it's evident
that it first scans integers from the array and then enters the hash,
so a first idea could be something like this:

function non_inext(t, k)
    if k==nil or isinteger(k) then
        k = next(t, k)
    end
    if isinteger(k) then
        return next(t, #t)
    end
    return k
end


but that not only is heavily implementation-dependent but i'm sure
there are some very undefined cases.  for example, imagine a valid
sequence with keys 1..1000, and a few other non-integer keys, but
where the last 100 integers (from 901 to 1000) are in the hash.  #t
would be 1000, but the original next() function could do something
like

1,2, 3,...,899,900, "a", 901,"x",943, 917, "w", 1000, 947..........,nil

that is, not even knowing about the current "first array then hash"
behaviour of next() makes any guarantee about integers in the hash.
my non_inext() would return 947 indefinitely, and even if i add more
tests to avoid integers it would skip "a","x" and "w".


in short, i think that if you need efficient non-integer iteration,
then don't mix integers in your non-integer table.


-- 
Javier