Log In  

According to the PICO-8 0.2.2c manual, "To remove an item at a particular index, use deli"

del  t v

    Delete the first instance of value v in table t
    The remaining entries are shifted left one index to avoid holes.
    Note that v is the value of the item to be deleted, not the index into the table.
    (To remove an item at a particular index, use deli instead)
    del returns the deleted item, or returns no value when nothing was deleted.

        A={1,10,2,11,3,12}
        FOR ITEM IN ALL(A) DO
            IF (ITEM < 10) THEN DEL(A, ITEM) END
        END
        FOREACH(A, PRINT) -- 10,11,12
        PRINT(A[3])       -- 12

deli t [i]

    Like del(), but remove the item from table t at index i.
    When i is not given, the last element of the table is removed and returned.


However, this does not seem to work with string or float indices. (Only tested on macOS Mojave)
The desired result can be achieved using

t[i] = nil

which seems to be the accepted way in lua.
Possible resolutions:

  • Update deli(t,i) to work with all index types
  • Update PICO-8 manual to specify deli only works with integer indices, and include t[i]=nil workaround.

thank you :)

P#89289 2021-03-21 03:16

2

I can't see the Problem there. "deli" is the PICO8-Way of using "table.remove". It also moves every Entry on the Table to the new Place to avoid "nil"-Entries.

Can you give us an example where this doesn't work?

"t[i]=nil" is only accepted if you use a Table as a "Key-Value"-like Variable. But if you use it as an "Array"-like Variable (for example, you need a Sequence of Variables in the right order), you better use "deli" (or "table.remove" in Lua) to not break anything.

Yes, Tables are a bit more complex^^.(It's also possible to do "Key-Value"- and "Array"-like at the same Table, but I won't recommend that...)

For example: Using Tables in a "Key-Value"-like way, you can't be sure that "#t" will give you the right Value:

cls()
tbl = {}
tbl["a"] = 22
tbl["b"] = 33
tbl["c"] = 44
print(#tbl) -- will print "0"

If you need to iter trough all Entries in a "Key-Value"-Table, you need to use these:

cls()
for k,v in pairs(tbl) do
 print(k.."="..v)
 -- it works, but you don't
 -- know the order
end

In this Scenario, it's okay to use "tbl[x]=nil".

However, in a "Array"- or "Sequence"-like Table, you want to use "del", or "deli" (or in Lua "table.remove") to not break something. For example:

-- DON'T DO THIS!
cls()
tbl = {11,22,33}
tbl[2] = nil
print(#tbl) -- it still prints 3

And this will also break FOR-Loops that iterate though a table:

-- DON'T DO THIS!
cls()
for i=1,#tbl do
 print(tbl[i])
 -- will print "11,[nil],33"
end

The (not so) "Fun"-Part is, it will break IPAIRS even worse:

-- DON'T DO THIS!
cls()
for i,v in ipairs(tbl) do
 print(i..": "..v)
 -- it only prints "1: 11"!
end

It skips the Value "33" completely because of the Value NIL on Index 2 in the Table!

Maybe it's possible to use "pairs" to overcome that, but it's more like a (ugly) Workaround for a Problem that can be completely avoided. Just simply use "del" (or "deli") on "Array"-like Tables, and it won't break "#tbl" and/or FOR-Loops that iterate through a Table.

(Sorry for that long Post, but I NEED to say that using "t[i]=nil" isn't a solution in every case. Using it in the wrong situation can lead to broken code^^)

With that said, I can't reproduce the Bug. It seems working normal here^^:

cls()
tbl = {11,22,33}
deli(tbl, 2)
for i,v in ipairs(tbl) do
 print(i..": "..v)
 -- prints "1: 11
 -- 2: 33"
end
P#89293 2021-03-21 05:32
2

Agreed that it’s a documentation issue.
Some functions are only for sequence tables: add, all, foreach, deli, #

P#89312 2021-03-21 17:11
4

(I'll write my own version of what's already been said, largely so you'll get the feeling you're getting consistent feedback on this.)

Given a lua table called table, there's a difference between keys and indices when referencing its values:

  • Keys are arbitrary values of arbitrary type that can dereference any and every value in table. Unlike indices, they have no implicit order, and there may be conceptual gaps between them.

  • Indices are whole numbers between 1 and #table that can be used to dereference the subset of values in table that are called its sequence. Sequences are roughly analogous to arrays, apart from beginning at index 1 instead of offset 0 as with arrays. Indices are intended to be ordered and contiguous from 1 to #table.

As @merwok said, some functions are designed to manipulate only the sequence portion of a table, e.g. add(), del(), deli(), foreach(), or the iterators all(), ipairs(). They should only be adding or manipulating values at whole-number indices, and they should be maintaining the #table counter appropriately so the program can quickly query how long the sequence is without having to scan the values to find the first nil.

I can't remember for sure, but I think Lua is meant to be able to recognize that a table is actually a pure sequence, and thus represent it internally in a way that is as compact and efficient to access as a simple raw array would be. I don't know if this ended up being true in practice, but I believe it was the purpose of having this concept of a "sequence" subset of the concept "table".

TL;DR: The previous answers are correct; you're not meant to be able to use something other than 1..#table for parameter i in deli(table, i).

(It's an understandable misunderstanding, by the way. It's a semantic difference in Lua that we all have to learn at some point, and usually the hard way.)

P#89359 2021-03-22 17:12 ( Edited 2021-03-22 17:24)

[Please log in to post a comment]

Follow Lexaloffle:          
Generated 2024-03-29 08:33:55 | 0.018s | Q:14