Hello:
I was having this strange error I couldn't find for hours occurring in PICO. I finally isolated it in new code where I created an array that was sized 64 and when I typed in to test the length of the array:
print(#xfer) |
I got back 63, not 64, despite there being 64 elements ! Where is the missing element ??
array="1234567890123456789012345678901234567890123456789012345678901234" xfer={} for i=0,63 do xfer[i]=sub(array,i+1,i+1) end cls() print(#array) print(#xfer) |
dw, lua tables start at 1.
array="1234567890123456789012345678901234567890123456789012345678901234" xfer={} for i=1,64 do xfer[i]=sub(array,i,i) end cls() print(#array) print(#xfer) |
UB, I can start at any number and still not get the total number of elements, if I don't start with one "1." Try this:
array="1234567890123456789012345678901234567890123456789012345678901234" xfer={} for i=2,65 do xfer[i]=sub(array,i-1,i-1) end cls() print(#array) print(#xfer) |
If you check in the initial code I wrote above, ALL array elements are being recorded, 64 of them. Same with the first post above.
The results should both be 64 ... that is unless "#" doesn't really count the correct number of elements in an array and instead just retrieves the last recorded array index ?
This works, but I shouldn't have to do this:
-- return correct size of array function arraysize(a) local r=0 for b in all (a) do r+=1 end return r end--arraysize(.) array="1234567890123456789012345678901234567890123456789012345678901234" xfer={} for i=2,65 do xfer[i]=sub(array,i-1,i-1) end cls() print(#array) print(#xfer) print(arraysize(xfer)) |
'#' does not return the number of elements in an array; it only returns the number of elements in arrays starting at index 1 with no holes. Any other use is undefined behaviour AFAIK.
samhocevar is correct.
dw187, you call them "arrays", but there is no such thing in Lua. There are only tables.
Tables can be used for many different things. They are in essence hash tables (also called associative arrays, dictionaries, etc) and can be used for that, or as objects/prototypes in an object oriented way, and so on.
And among all those other things, Lua tables can be used as arrays. This is called a "sequence", and a sequence consists of those elements of a table starting from index 1 and up, one integer at a time, until an element is nil. The # operator only counts elements that are part of a sequence.
https://www.lua.org/manual/5.2/manual.html#3.4.6
A table can contain a sequence, plus any number of elements outside that sequence; elements with an index of 0, for example, or an index that is a string, or anything else.
t={1,2,3} -- t is a sequence of 3 elements, #t will be 3 add(t,4) -- this adds an element to the sequence, #t is now 4 t[0]=0 -- this adds an element outside the sequence, #t is still 4 t[0.5]=0.5 -- ditto; #t is still 4 t["foo"]="foo" -- a string index is not part of a sequence; #t is still 4 t.bar="bar" -- equivalent to a string index like above; #t is still 4 t[6]=6 -- this is also outside the sequence since t[5] is nil; #t is still 4 add(t,5) -- does the same as t[5]=5 here, ie. it adds an element to the end of a sequence. this connects the sequence with the 6 we added above. #t now goes from being 4 to 6! |
However, this is where "undefined" enters the picture. A Lua implementation can implement # so that it counts non-sequences differently. PICO-8 does it like I said above though.
Seems like I have a great deal yet to learn about Pico-8 and LUA for that matter. Only recently did I realize you can have a valid number stored in a negative index, like value[-1]="apple" and the reverse which is also true, value["apple"]=-1. Tricky stuff to learn since I've only programmed in true BASIC type languages. :)
So I guess my initial question is, is there a shortcut like "#" that will count the number of elements in a table (or array for that matter) - without having to write a function to do so ?
Where a table that starts with index 0, provided it does indeed have 64-elements in it, will indeed return the number 64 despite what data it contains or index it references ?
No, you'll have to write a function.
And note that the function must use pairs() to traverse the table – all() only returns elements in a sequence. (The latter also returns them in order, while the former is not guaranteed to be ordered.)
OK, well thanks for that, guys. I'll just need to be careful if I use any arrays (tables) that don't start with 1. Strings fortunately still work:
fruit="papaya" print(#fruit) |
Returns 6.
I also noticed that due to how Lua handles them, tables indexed from 1 tend to be significantly faster than when indexed from 0.
You should really try to stick with 1-indexing unless you have a good reason.
[Please log in to post a comment]