nick
nick

Reputation: 51

What happens when you remove a value from the middle of an array?

If I have an array like this:

local array = {'foo', 'bar', 'baz'}

And I remove the second element like this:

array[2] = nil

Would this send array[3] and any larger index to the hash part of a table? Or does it just leave a hole in the array portion?

Upvotes: 5

Views: 347

Answers (3)

Piglet
Piglet

Reputation: 28950

It will add a another border.

This has a few effects:

  1. you can no longer use ipairs to get all your elements as ipairs will stop at the first border
  2. the length operator # will no longer give you the number of elements in that table as it may return any border.
  3. table.concat will raise an error invalid value (nil) at index 2 in table for 'concat'
  4. some functions in the table library will no longer work for values after the border

See

Upvotes: 2

koyaanisqatsi
koyaanisqatsi

Reputation: 2793

That leaves a hole.
Therefore exists: table.remove()

You have to specialize your tools than. For example a tprint() that can handle it...

tprint=function(tab,...)
local args={...}
local start=args[1]
local stop=args[2]

if type(args[1])=='number' and type(args[2])=='number' then
 warn('Using numbers for table print out')
 for i=start,stop do
  io.write(string.format('%d = %s\n',i,tab[i])):flush()
  if start==stop then return tab[i] end
 end
else
 warn('Using pairs() for table print out')
 for key,value in pairs(tab) do
  io.write(string.format('%s = %s\n',key,value)):flush()
 end
end

end

Than you can do things like...

>tprint(arg)
Lua warning: Using pairs() for table print out
1 = -W
2 = -i
3 = -e
4 =  dofile('/root/lua/tprint.lua')
0 = /root/bin/lua
1618128658 = It is alive!!!
1618129059 = function: 0x566bf0f0
1618129084 = function: 0x566bfba0
1618128894 = tprint
>tprint(arg,1618128658,1618128658)
Lua warning: Using numbers for table print out
1618128658 = It is alive!!!
It is alive!!!

...or a sequence from 0 to 4 ...

>tprint(arg,0,4)
Lua warning: Using numbers for table print out
0 = /root/bin/lua
1 = -W
2 = -i
3 = -e
4 =  dofile('/root/lua/tprint.lua')

Upvotes: 1

Doyousketch2
Doyousketch2

Reputation: 2147

you can put remaining entries into a new list, to essentially close that gap

newarray = {}
for i = 1, #array do
    if array[i] then 
        newarray[ #newarray ] = array[i]
    end
end

or nudge them all down one position, using multiple assignment to flip-flop entries ( index 3 into 2, 2 into 3... ) leaving that nil as the final entry, so things behave as expected.

for i = 1, #array do
    if not array[i] then 
        array[i], array[i+1]  = array[i+1], array[i]
    end
end

Upvotes: 0

Related Questions