Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What exactly does table.move do, and when would I use it?

Tags:

lua

The reference manual has this to say about the table.move function, introduced in Lua 5.3:

table.move (a1, f, e, t [,a2])

Moves elements from table a1 to table a2, performing the equivalent to the following multiple assignment: a2[t],··· = a1[f],···,a1[e]. The default for a2 is a1. The destination range can overlap with the source range. The number of elements to be moved must fit in a Lua integer.

This description leaves a lot to be desired. I'm hoping for a general, canonical explanation of the function that goes into more detail than the reference manual. (Oddly, I could not find such an explanation anywhere on the web, perhaps because the function is fairly new.)

Particular points I am still confused on after reading the reference manual's explanation a few times:

  • When it says "move", that means the items are being removed from their original location, correct? Do the indices of items above the removed items shift down to fill the gaps? If so, and we're moving within the same table, does t point to the original location before anything starts moving?
  • Is there some significance to the choice of index letters f, e, and t?
  • There is no similar function in any other language I know. What's an example of how I might use this? Since it's one of only seven table functions, I presume it's quite useful.
like image 992
Soren Bjornstad Avatar asked Oct 26 '25 06:10

Soren Bjornstad


2 Answers

Moves elements from table a1 to table a2, performing the equivalent to the following multiple assignment a2[t],··· = a1[f],···,a1[e] Maybe they could have added the information this is done using consecutive integer values from f to e.

If you know Lua a bit more you'll know that a Lua table has no order. So the only way to make that code work is to use consecutive integer keys. Especially as the documentation mentions a source range.

Giving the equivalent syntax is the most unambiguous way of describing a function. If you know the very basic concept of multiple assignment in Lua (see 3.3.3. Assignment) , you know what this function does.

table.move(a1, 1, 4, 6, a2) would copy a1[1], a1[2], a1[3], a1[4] into a2[6], a2[7], a2[8], a2[9]

The most common usecase is probably to get a subset of a list.

local values = {1,45,1,44,123,2354,321,745,1231}

old syntax:

local subset = {}
for i = 3, 7 do
  table.insert(subset, values[i])
end

new:

local subset = table.move(values, 5, 7, 1, {})

Or maybe you quickly want to remove the last 3 values from a table?

local a = {1,2,3,4,5,6,7}
table.move({}, 1,3,#a-2, a)
like image 168
Piglet Avatar answered Oct 28 '25 00:10

Piglet


When it says "move", that means the items are being removed from their original location, correct?

Surprisingly not. Items are copied from the source range to the destination. If the source range is nil or empty, nils are placed in the destination.

src={5,6,7} 
table.move(src,1,2,3)
-- src is {5,6,5,6}

src={5,6,7} dest={0,0,0} 
table.move(src,1,2,3,dest)
-- src remains {5,6,7} dest is {0,0,5,6}

src={} dest={0,0,0} 
table.move(src,1,1,2,dest)
-- dest is {0,nil,0}

The function seems poorly named, however it has been related to a C function called memmove, which also does not remove the source range. memmove is equivalent to memcpy except memmove is safe to move a source range on top itself. With table.move it is also safe to move ranges over themselves (it is buffered). This might go some way to rationalizing how the function is named.

like image 44
strainer Avatar answered Oct 27 '25 23:10

strainer