1

Given

local t1 = {
    ["foo"] = "val1",
    ["bar"] = "val2",
    ["baz"] = "val3",
}

local t2 = {
    ["foo1"] = "val4",
    ["bar1"] = "val5",
    ["baz1"] = "val6",
}

Id like to get result

local t3 = {
     ["foo"] = "val1",
     ["bar"] = "val2",
     ["baz"] = "val3",
     ["foo1"] = "val4",
     ["bar1"] = "val5",
     ["baz1"] = "val6",
}

I have been attempting various ways for around a day now, using other questions provided here, and still am unsure of where things are going wrong or how to handle it. The tables vs arrays in lua is a bit hard to grasp. Thanks for any help :D

Paracelsus
  • 11
  • 1
  • [also look here](https://stackoverflow.com/questions/1283388/how-to-merge-two-tables-overwriting-the-elements-which-are-in-both) – Mike V. Oct 13 '22 at 07:46
  • There is no ordering to maintain; hash tables are unordered. If they happen to be ordered in your particular example it's just luck. – Luatic Oct 13 '22 at 12:27
  • You will need to use pairs or similar, e.g. `t1 = {{"foo", "val1"}, {"bar", "val2"}}` to have an order. – Luke100000 Oct 14 '22 at 06:25

1 Answers1

2

AFAIK, if the hash part of a table is used, it does not preserve the order. There is a very simple way to highlight this.

t1 = {
    ["foo"] = "val1",
    ["bar"] = "val2",
    ["baz"] = "val3",
}

for k,v in pairs(t1) do
  print(k, v)
end

On my computer, the order is not preserved:

foo     val1
baz     val3
bar     val2

If the order is important, it is required to use an array.


One (convoluted) way to do it would be the following code. Obviously, I am not aware of the given requirements, so this code might not be the most straight-forward.

t1 = {
  { foo = "val1" }, -- Element t1[1]
  { bar = "val2" }, -- Element t1[2]
  { baz = "val3" }  -- Element t1[3]
}

t2 = {
  { foo1 = "val4" }, -- Element t2[1]
  { bar1 = "val5" }, -- Element t2[2]
  { baz1 = "val6" }  -- Element t2[3]
}

function merge (t1, t2)
  local new_table = {}
  -- Copy all the items from the first table
  for index = 1, #t1 do
    new_table[#new_table+1] = t1[index]
  end
  -- Copy all the items from the second table
  for index = 1, #t2 do
    new_table[#new_table+1] = t2[index]
  end
  -- return the new table
  return new_table
end

for k,v in pairs(merge(t1,t2)) do
  local subtable = v
  for k,v in pairs(subtable) do
    print(k,v)
  end
end

This would print the following:

foo     val1
bar     val2
baz     val3
foo1    val4
bar1    val5
baz1    val6
Robert
  • 2,711
  • 7
  • 15
  • This will only work with tables with integer indexes, in our case: `#t1==0` And besides, this comment is fundamentally wrong: `{ foo = "val1" }, -- Element t1[1]` , because `t1[1]==nil` – Mike V. Oct 13 '22 at 07:44
  • Yes it only works with tables with integer indexes, that's the whole point, as hashtables don't preserve the ordering. This is the first thing I highlighted in my answer. – Robert Oct 13 '22 at 09:24
  • No, in our case #t1 is not 0, #t1 is 3 because it contains 3 elements. – Robert Oct 13 '22 at 09:27
  • yes, sorry, I didn't see the table inside the table)) – Mike V. Oct 13 '22 at 11:48