1
votes

I have three tables. One with integers, one with strings, and one that is empty. All three tables are filled automatically. Once the first two tables are filled (both having equal entries) I want the third table to fill itself where each entry's key is the value from table 'a' and each entry's value is the value from table 'b'. Table 'a' will always have unique values. I'm new to lua so please be as specific as possible.

Example:

a = {"joe", "bob", "bill"}
b = {"24", "111", "32"}
c = {joe = "24", bob = "111", bill = "32"}

My current tables are created like this:

a = {}
b = {}
c = {}

functionThatPopulatesTableA()
end

for i, #a do
   b[i] = functionThatReturnsSpecificValue()
end

My attempt to fill table c ended up looking like this:

function charlie()
    for k, v in pairs(a) do
        c[v] = a[v]
        c[k] = b[v]
    end
end

Needless to say, that did not work.

2
Okay, on a whim, I tried function charlie() for k, v in pairs(a) do c[k] = a[v] c[v] = b[k] end end And it works?? Why does this work? table 'b' should only have values, and indices as keys right? So table 'b' keys should be 1, 2, ... Yet when I use c[v] = b[k] it returns b's value as if it's b's key - Nick

2 Answers

0
votes

You need to think more critically about what the "keys" and "values" are in each case.

Try thinking through this like you're the computer:

for k, v in pairs(a) do
    c[v] = a[v]
    c[k] = b[v]
end

So, your loop through a from your example will look like this:

k       v
--------------
1       "joe"
2       "bob"
3       "bill"

So, c[v] = a[v] becomes c["joe"] = a["joe"] which becomes c["joe"] = nil, because a["joe"] is not defined. So it should be obvious that this won't work.

Now, let's look at the function that worked:

for k, v in pairs(a) do 
    c[k] = a[v]
    c[v] = b[k] 
end

This is still not quite correct, though it does end up working for you in the end. For instance, using the same example as before, c[k] = a[v] becomes c[1] = a["joe"], which becomes c[1] = nil because a["joe"] is nil. This line can be removed from the function because it doesn't actually do anything; all table values which are undefined are nil.

Next, c[v] = b[k] becomes c["joe"] = b[1] which becomes c["joe"] = 24, which is what you want.

0
votes

I assume your tables a & b are just arrays of values:

a = {"joe", "bob", "bill"}
b = {"24", "111", "32"}

In this case (if you have no nil values inside) you can use common for loop (# is length operator, which gives you array size)

--handling case when tables have different number of elements
local minSize = math.min(#a, #b)
for i = 1, minSize do
    local key = a[i] -- take key from table a
    c[key] = b[i] -- put appropriate value from b
end

this code will not work in case when you have tables with nil values inside like:

a = {"joy", nil, "bill" } 
b = {"24", nil, "32"}

So with nil values use pairs (I fixed your code - see comments):

for k, v in pairs(a) do
    -- k is equal to index in table a
    -- v is table value for this index        
    c[v] = b[k]
end

If we take table above as example it will work following way:

for loop started
picked k = 1, v = "joe"
c["joe"] = b[1]
picked k = 3, v = "bill" (remember, we set element 2 to nil?
c["bill"] = b[3]
for loop ended