Looking at the documentation, it doesn't seem like it. If you have control over how your strings are created though you could just put the "first" (zero indexed) element at the end of the string then do something like this:
col=split("9,8,4,10") -- 10 will end up in index 0 col[0] = col[#col] col[#col] = nil |
This should still save you tokens in general. (Assuming your lists are going to be longer than 4 elements.) Not ideal but it'll get the job done if working with 1-based arrays really isn't an option.
If you don't have control over how your strings are created then this may not be an option.
Hi @jasondelaat:
Thanks for writing !
Checking ...
That does indeed work. Complex. Is there a way that uses less tokens ?
Zero base is not an option, I've just always felt more comfortable starting every array with zero.
I know I can use:
col={[0]=10,9,8,4} |
However SPLIT() is a command I just recently learned so I'm trying to master it - to see if I can get a zero base out of it.
I realized a few days ago that you can swap variables like so:
a, b = b, a |
And if you leave values off the right-hand side of that the corresponding values will get set to nil. So you can save a couple tokens by doing it like this:
col[0],col[#col]=col[#col] |
Other than that I can't really think of a more efficient way to do it, though someone else might have suggestions.
If you have to do this often you can put it in a function so you only pay the token cost once.
function reindex(lst) lst[0],lst[#lst]=lst[#lst] end |
Costs a few more tokens to define and a couple tokens each time you call it. But the more often you call it, the more tokens you save overall.
I think you gave me an idea, @jasondelaat. Try out this code:
a=split("0,1,2,3") foreach(a,shift) for i=0,3 do ?a[i] end function shift(n) a[n-1]=a[n] end |
0
1
2
2
Not the right results but closer. I think for now I'll just use:
[code]
a={[0]=0,1,2,3}
I have to admit SPLIT is a lot better than what I had to do in QBASIC using INSTR() to look for "," and separate the data manually based upon its position (and count) in a string.
To reassign items in a sequence to their numeric index minus 1:
-- 17 tokens: function shift(t) t[0]=t[1] deli(t,1) return t end -- 7 tokens, composed functionally with split(): a=shift(split("0,1,2,3")) -- shift() modifies the table in place, so you can also do (8 tokens): a=split("0,1,2,3") shift(a) |
If modifying in place is sufficient (as in the second example), you can remove the return statement and save two tokens.
To create a new shifted sequence without modifying the original, use this table cloning trick with unpack():
-- 13 tokens: orig=split("0,1,2,3") a=shift({unpack(orig)}) |
You probably know this, but for posterity: Lua's sequence operations all assume 1-based indexes, so the shifted "sequence" isn't really a sequence, it's a sequence with its first term removed and reassigned to non-sequence index 0.
assert(a[0] == 0) assert(a[1] == 1) assert(a[2] == 2) assert(a[3] == 3) assert(#a == 3) -- not 4 -- prints 1 2 3 for v in all(a) do print(v) end |
One final thought on this @dw817. Building on @dddaaannn's shift function, if you're sure you always want 0 based indexes you could redefine split like so:
-- 27 tokens _split = split function split(...) local l = _split(unpack{...}) l[0] = l[1] deli(l, 1) return l end |
And then you just use it like normal except you get 0-based arrays instead of 1-based. Including the potential downsides mentioned above.
col='1,2,3,4' -- 5 tokens per call to split c = split(col) -- or 4 if called with a string literal and no parens -- c = split'1,2,3,4' for i=0,4 do print(c[i]) -- c[4] should be nil end |
which prints
1 2 3 4 [nil] |
as expected.
And it'll work with the same arguments that normal split works with, so this would also work splitting on spaces instead of commas.
col='1 2 3 4' c = split(col, ' ') for i=0,4 do print(c[i]) end |
You can decide for yourself whether redefining standard functions is a good idea or not but it is a possibility.
Oh wow, @jasondelaat. You see it's code like @dddaaannn's I can't understand with a darn. Yet that is exactly what I'm looking for. Zero base SPLIT.
Verified that the UNPACK command works with v0.2.1b. That's the cellphone version of Pico-8.
Code size has never really been a problem for me except in one of my older games. So the new SPLIT command he wrote, yes, that will do very nicely, with full credit to him.
Thanks for bringing this to my attention !
-- zero base split by dddaaannn _split = split function split(...) local l = _split(unpack{...}) l[0] = l[1] deli(l, 1) return l end cls() a=split("pears,bananas,grapes") for i=0,2 do ?a[i] end |
Works beautifully !
pack/unpack added v0.2.0i according to the release notes. (I imagine the ... operator was always there but useless without pack/unpack. :) )
from the manual:
"Because table indexes start at 1, colour 0 is given at the end in this case."
when you use it for the "Pal"-Command, you can simple use position 16 as color 0.
another approach that I use sometimes:
function arr0(zero,arr) arr[0]=zero return arr end altpalette=arr0(0x80,split"0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f") |
[Please log in to post a comment]