This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Sewbacca's profile picture

close table gaps

Started by Sewbacca, 23 March 2016 - 08:21 PM
Sewbacca #1
Posted 23 March 2016 - 09:21 PM
Look at this example:


{
  [1] = 'foo',
  [3] = 'foo2',
  [4] = 'foo3',
  [24] = 'foo4'
}

Which function allows to close gaps?
So into this:


{
  'foo', 'foo2', 'foo3', 'foo4'
}
Creator #2
Posted 23 March 2016 - 09:31 PM
Not visually, right? You mean the indexes?


newTable = {}
index = 1
for i,v in pairs(oldTable) do
  newTable[index] = v
  index = index + 1
end
Yevano #3
Posted 23 March 2016 - 09:42 PM
Not visually, right? You mean the indexes?


newTable = {}
index = 1
for i,v in pairs(oldTable) do
  newTable[index] = v
  index = index + 1
end

This will change the array to be in random order, so if the order matters this won't work.
Creator #4
Posted 23 March 2016 - 09:46 PM
Not visually, right? You mean the indexes?


newTable = {}
index = 1
for i,v in pairs(oldTable) do
  newTable[index] = v
  index = index + 1
end

This will change the array to be in random order, so if the order matters this won't work.

I believe pairs returns number indexes in the correct order.
Lupus590 #5
Posted 23 March 2016 - 09:58 PM
ipairs instead of pairs
Edited on 23 March 2016 - 10:32 PM
KingofGamesYami #6
Posted 23 March 2016 - 10:03 PM
ipairs wouldn't get to 14. It stops at the first nil (5).


local newTable = {}
for i = 1, table.maxn( oldTable )
  newTable[ #newTable + 1 ] = oldTable[ i ]
end

Logic: iterate from 1 to the largest index in oldTable (14). Each time, add an element to newTable. #newTable won't increase if the previous element in oldTable was nil, so it removes gaps.
Lyqyd #7
Posted 23 March 2016 - 10:30 PM
If the table starts out with no gaps, you can use table.remove to remove entries without creating gaps. It's much easier to keep your tables gap-free than to clean them up after introducing gaps. Of course, if your table starts out with gaps, you'd need to use one of the options above.

The best option may be to make a table containing the numeric keys, sort that table, then iterate that table and use the key/index pairs in it to move around values in the original table.
Sewbacca #8
Posted 24 March 2016 - 09:20 AM
If the table starts out with no gaps, you can use table.remove to remove entries without creating gaps. It's much easier to keep your tables gap-free than to clean them up after introducing gaps. Of course, if your table starts out with gaps, you'd need to use one of the options above.

The best option may be to make a table containing the numeric keys, sort that table, then iterate that table and use the key/index pairs in it to move around values in the original table.

I thought to use table.remove, but this would create issues.
Not visually, right? You mean the indexes?


newTable = {}
index = 1
for i,v in pairs(oldTable) do
  newTable[index] = v
  index = index + 1
end

This will change the array to be in random order, so if the order matters this won't work.

I believe pairs returns number indexes in the correct order.

I think this is the best solution, thanks.
Yevano #9
Posted 24 March 2016 - 09:53 PM
I believe pairs returns number indexes in the correct order.

Not always, particularly if the input table is sparse. I'm guessing this happens because sparse indices will get shoved into the hash part of the table, though I don't know the exact behavior. I wouldn't rely on pairs for iterating in a particular order unless I was certain the input table only consists of an array part.
Bomb Bloke #10
Posted 24 March 2016 - 11:49 PM
I'm guessing this happens because sparse indices will get shoved into the hash part of the table, though I don't know the exact behavior.

That's exactly the way tables are constructed, yes: if the values are added in order and with no gaps, LuaJ sticks them into an array (occasionally making a new array and copying over all the old indexes if it runs out of room). If there are gaps between values, then they get hashmapped instead; otherwise, making a new table and sticking something into index 1000000 would result in LuaJ creating a stonking great array with nothing in it.