5

I got two tables, for example:

table1 = { element1, element2, element3, element4 }
table2 = { element1, element3 }

Table 2 refers to some elements of table1, but I don't know which exactly, nor I know their index. Now, for an specific element I want to check if table2 does contains it or not and insert/remove it in the case.

First thing that jumped to my mind was:

table.remove/insert(table2, table1.elementX)

But due insert/remove does its lookup by index, this doesn't work. Sure, I could iterate through the whole table until I find the element and remove it, respectively until Iteration is done without match and insert it.

But is there a more performant method to do this?

I do not want to fill table2 with empty fields for bringing the elements on matching indices.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
jawo
  • 856
  • 1
  • 8
  • 24
  • What problem are you really trying to solve with this? – lhf Sep 29 '14 at 10:57
  • Excuse me? I want to insert/remove a element of table1 to table2, depending on if it's already inside or not. – jawo Sep 29 '14 at 11:26
  • Do you mean that table1 is a reference, and if table2 does not contain an element that is in table1, you want to add the element to table2, where if table2 has an element that is not in table1, you want to remove the element from table1? but if so, then you will end up with table1 = table2 so surely that's not what you want, can you clarify? – Oliver Sep 29 '14 at 12:47
  • Yes but, as I said, only "for an specific" (from table1), not for all. – jawo Sep 29 '14 at 12:49

3 Answers3

0

To insert, it's quite straightforward:

table.insert(table1, table2[index])

Unfortunately, to remove, it's a bit more tricky:

local ids = {} -- table containing ids to remove
for i,v in ipair(table1) do
  if v == table2[index] then
    table.insert(ids, 1, i) -- "1" preprends the value
end

-- At this point, "ids" contains all the ids to remove in the reverse order

for k,v in pair(ids) do
  table.remove(table1, v)
end

What happens here is:

  1. An intermediate table is created, it only contains the ids of the table to remove, descending. For example: { 6, 3, 1} (if the value is present 3 times).

  2. That intermediate table is used to update the main table, as you can't use the ids from a table you are updating in a loop (that's what the comments about "transversal" mean).

    Note that those operations must be made from the end of the table, because removing an element will change the ids of the following ones.

SteeveDroz
  • 6,006
  • 6
  • 33
  • 65
-1
for k,v in pairs(table1)do
  if v == table2[index] then
  table.remove/insert(table1, k)
  break
end

Of course this works, but I still hope there's a more performante solution. Due in case of multiple 1000 entrys in table1 and multiple 100 entrys in table2, this is will lead to high cpu usage, wich I want to avoid. (programming a controller with only 200mhz)

jawo
  • 856
  • 1
  • 8
  • 24
  • 2
    You cannot use `table.insert(table1,x)` inside a traversal of `table1` because it potentially creates new fields. – lhf Sep 29 '14 at 11:03
-1

First revert table2 with

table2reverse = {}
for k,v in pairs(table2) do table2reverse[v]=k end

Then do this:

for k,v in pairs(table1)do
  if table2reverse[v] then
    table1[k]=nil
end

Finally compact table1.

lhf
  • 70,581
  • 9
  • 108
  • 149