lua-users home
lua-l archive

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


hi, so, a lot of ppl won't use Lua because Lua uses 1-based indexing. well, other languages use 0-based indexing. but, what if we had neither?

the trivial solution for "neither" is just to use linked lists. and that would, indeed, work, quite badly as well.but what if we come up with something completely different instead?

rather than limiting ourselves to numeric representations of arrays, I suggest a much more tangible (and yes tangible is the right term) approach: filters.

consider the following table:

local t = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

(also consider as if t[1] etc don't work to access array indexes but only hashtable indexes)

how do you iterate it? well you'd still use ipairs ofc and it'd be just as fast, it just wouldn't use numbers. so you'd do "for value in ipairs(table) do". additionally we can also remove array indexes from pairs() because it doesn't make any sense to keep them there.

how would you do indexing? well, this is where things get interesting. let's say you want to get that 5 there. you could do it like this:

local i = {false, false, false, false, true}
local v = table.get(t, i) -- v = 5

great! we no longer need numeric indexing! oh, wait...

uhh... how would we dynamically index things...

well, one thing is consistent between 0-based indexing and 1-based indexing: in 0-based indexing, the length is always just beyond the last valid index. in 1-based indexing, the length is the last valid index. this happens to match up with the number of values in the array. as such we can keep #t.

one option is to have "left, mid, right = table.bisect(t)". this is quite efficient as well.

local left, mid, right = table.bisect(t) -- mid is nil
local left, mid, right = table.bisect(right) -- mid is 8
local left, mid, right = table.bisect(left) -- left is 6, right is 7, mid is nil

(having a separate mid lets we ignore the problem of bisecting an odd number and having to decide which side it'll go to.)

combine it with #t and you can trivially do 0-based or 1-based indexing in your own code, and it just works. you can even mix them in the same code, which is useful in some contexts.

okay so we have bisect and all but this isn't complete yet. to really finish it off we need one more thing. well, four, actually: table.pop_left, table.pop_right, table.push_left, table.push_right. additionally, table.bisect should return views, not full arrays, both so it's faster and so we can pop_left on a view and have it modify the original table.

but anyway, this way, everyone's happy, because numeric indexing is no more. or, well, actually, it's meant to make everyone unhappy I guess, but you get the point xd.