[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: So I had this weird idea to solve the indexing problem
- From: "Soni \"They/Them\" L." <fakedme@...>
- Date: Sun, 9 Jun 2019 08:05:31 -0300
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.