So I was looking for a nice efficient way to accomplish a table comparison. I have a way that works, but it involes a lot of looping throught the lists and it's not something that I'm really happy with. Here's my example:
-- Names used without permission. :D
TableA = {"Tekhub", "Kaelten", "ckknight", "Xinhuan", "Kaelten"} --Max 10 entries
TableB = {"ckknight","Tekhub","OrionShock"} --Max 10 entries
By the end of the process I'd like TableA to contain only entries not in TableB and vice-versa. Also, TableA may contain duplicates initially, but should not contain any at the end of the process.
local tempA, tempB = {}, {}
for _, v in ipairs(TableA) do
tempA[v] = true
end
for _, v in ipairs(TableB) do
tempB[v] = true
end
wipe(TableA)
wipe(TableB)
for v in pairs(tempA) do
if not tempB[v] then TableA[#TableA + 1] = v end
end
for v in pairs(tempB) do
if not tempA[v] then TableB[#TableB + 1] = v end
end
-- optionally
table.sort(TableA)
table.sort(TableB)
Edit: Based on what you want to do, I strongly suggest that you try to use the data as a key in your table (equivalent to what I did with tempA/B) instead of using integer keys.
Thanks for you quick response. I think it's important that I understand exactly how this works so I just want to get a little clarification/confirmation.
local tempA, tempB = {}, {}
for _, v in ipairs(TableA) do
tempA[v] = true
end
for _, v in ipairs(TableB) do
tempB[v] = true
end
In the section above you're just using this to go from interger keys to data keys in a new table, correct? You're then wiping the original tables and then adding them back in (from the temp tables) based on whether or not they exist in the other list?
It's the first. In tempA, the names are the keys of the table (and their corresponding value is true). I'm interested in the keys and in the "for k[, v] in ..." construct, the first variable reference is to the key, and the second to the value.
I used t[#t + 1] because it's faster. The semantic is the same as calling table.insert
By the end of the process I'd like TableA to contain only entries not in TableB and vice-versa. Also, TableA may contain duplicates initially, but should not contain any at the end of the process.
Edit: Based on what you want to do, I strongly suggest that you try to use the data as a key in your table (equivalent to what I did with tempA/B) instead of using integer keys.
In the section above you're just using this to go from interger keys to data keys in a new table, correct? You're then wiping the original tables and then adding them back in (from the temp tables) based on whether or not they exist in the other list?
The only question I have is: Should it be
or
If it the first, can you please explain why?
instead of
Yes. This has the nice side effect of directly taking care of the duplicate entries in tableA.
Yes.
It's the first. In tempA, the names are the keys of the table (and their corresponding value is true). I'm interested in the keys and in the "for k[, v] in ..." construct, the first variable reference is to the key, and the second to the value.
I used t[#t + 1] because it's faster. The semantic is the same as calling table.insert
It's not as pretty, though.
Ugh. I've actually seen people who say that on WoW in regards to gear. Same principle. To hell with pretty - function over form!
Well there are those RP folks. Not that I'm one of them or anything.
First rule of engineering: Form follows function.
Second rule of engineering: Apply power.