Log In  

Hi

Short question this time. What is the least-bloated way to insert a value into a list at the first index using add(). I couldnt figure out a method which is elegant and simple.

Thanks

P#77539 2020-06-02 16:45

add(mytable, myvalue)
mytable[#mytable], mytable[1] = mytable[1], mytable[#mytable]

I don't think there's a much "smoother" way to do that...

P#77549 2020-06-02 17:36

Edit: For anyone coming across this at a later date, note that as of June 2020 pico-8 (PICO-8 0.2.1) has the following API changes:

"add() now comes with an optional 3rd parameter: an integer that specifies the location in the table that the new value should be inserted at. Similarly, a new variation of del() is available: deli(tbl, index) ("delete by index") allows deleting from a given location in the table rather than by value."

For full text, see zep's post: https://www.lexaloffle.com/bbs/?tid=38665


If you want to use add to insert a value at the index=1, and you want to shift all the values up by one (rather than just swap the first and last elements as Astorek86's code does) you could:

function _init()
 addatend=add
 add=newadd
end

function newadd(t,v)
 for i=#t+1,2,-1 do
  t[i]=t[i-1]
 end
 --insert new value
 t[1]=v
 return v
end

If your intention wasn't to repurpose add (an overly literal interpretation, probably), you could just name the new function addatstart and not do the renaming in _init.

I don't know that it's the least-bloated way of doing it, and it has to iterate over the whole list.


Edited to return v, as Felice has done with the insert example - being relatively new to Lua and pico-8 I was unaware of this return.

P#77555 2020-06-02 20:01 ( Edited 2020-07-04 11:51)

you could try

table = { new_value, unpack(table) }

it creates a new table though, so make sure you update other references to the old table anywhere else.
also no idea how fast it is when called repeatedly on large tables...

P#77558 2020-06-02 20:42 ( Edited 2020-06-02 20:42)
:: Felice
1

@Astorek86

You could skip the add() there:

mytable[#mytable+1], mytable[1] = mytable[1], mytable[#mytable]

Mind you, I don't think this is what the OP wanted.

I think the OP wants an insert function:

function ins(t,v,i)
  i=i or 1 -- default the insertion point to the head of the list
  for j=#t,i,-1 do
    t[j+1]=t[j]
  end
  t[i]=v
  return v -- do like add() and return the inserted value
end

mytable = {1,2,3}      -- {1,2,3}
ins(mytable, 0)        -- {0,1,2,3}
ins(mytable, "wow", 3) -- {0,1,"wow",2,3}
P#77568 2020-06-02 23:43 ( Edited 2020-06-02 23:51)

@ultrabrite clever! unpack cost is proportional to list size, but agree that allocation cost of the array might be a killer (vs swapping in place)

P#77580 2020-06-03 05:25

alternative is to add as usual and iterate array from the end 😬

P#77581 2020-06-03 05:27
:: tarkan

If you create a linked list (https://en.wikipedia.org/wiki/Linked_list), you'd be able to get the fastest insert at the beginning of the list. It's not stored in a single table now, but the memory constraint ends up being a constant multiple different, so it's not a big difference.

P#77583 2020-06-03 06:15

[Please log in to post a comment]

Follow Lexaloffle:        
Generated 2021-01-17 16:00 | 0.037s | 2097k | Q:25