Can we use table as key for dictionary?
This does not seem to work?
local K = {
[{"d", 12}] = 6,
[{"d", 18}] = 4,
[{"z", 11}] = 12
}
print(K[{"d", 18}]
Can we use table as key for dictionary?
This does not seem to work?
local K = {
[{"d", 12}] = 6,
[{"d", 18}] = 4,
[{"z", 11}] = 12
}
print(K[{"d", 18}]
It doesn’t work because they’re different references. When you use {} you’re creating a new table, the only way you could make this work is by for example creating the table in a variable and then using that variable as the key. Just because a table has the same things inside it as another one doesn’t mean it’s the same table.
you cant use tables as keys, instead you can do:
[6] = {"d", 12}
[4] = {"d", 18},
[12] = {"z", 11}
}
print(K[12])
and have the intended effect
Yes, you can, but you cannot construct two individual tables that would evaluate to the same due to different memory addresses.
local t = {name = "myname", value = 25}
local dict = {}
dict[t] = "string"
print(dict[t])
I was hoping to be able to use this as a way to fast find a pair inside a dictionary, but I guess I will have to use traditional FOR loop for searching…
Hello.
Yes, you can use tables as keys.
local t1 = {"d", 12}
local t2 = {"d", 18}
local t3 = {"z", 11}
local K = {
[t1] = 6,
[t2] = 4,
[t3] = 12,
}
print(K[t1]) -- Output will be 6
Please, notice that if you try accessing an index in your code, you should use the same reference to the table.
local t1 = {"d", 12}
local t2 = {"d", 12}
print(t1 == t2) -- Will output false
This happens because t1
stores the reference to the first table and t2
the reference to the second table. Although they are identical, you should always keep a reference if you want to find it inside another table.
Best regards,
Octonions
Use a 2D table:
local K = {
["d"] = {[12] = 6},
["d"] = {[18] = 6},
...
}
print(K["d"][12])
Or as an alternative, define the __eq metamethod and use table.find
:
do
local mt = {}
function mt.__eq(a, b)
--Tuples have value semantics for equality in languages like C#, so here's an implementation that does just that. ish, doesn't work for dictionaries, though you could MAKE it work.
local lenA, lenB = #a, #b
if lenA ~= lenB then return false end
for i = 1, math.max(#a, #b) do
if a[i] ~= b[i] then return false end
end
return true
end
function tuple(...)
return setmetatable({...}, mt)
end
end
function find(list, value)
for i, _value in ipairs(list) do
if _value == value then
return i
end
end
return nil
end
local a = tuple(1, 2, 3)
local b = tuple(1, 2, 3)
local c = tuple(1, 2)
local d = tuple(1, 2, 4)
local e = tuple(1, 2, 3, 4)
print(a == a) --T
print(a == b) --T --Same values, different object, still equals
print(a == c) --F
print(a == d) --F
print(a == e) --F
local things = {a}
print(find(things, a) ~= nil) --T
print(find(things, tuple(1, 2, 3)) ~= nil) --T
print(find(things, c) ~= nil) --F
I don’t know if table.find
is actually implemented like that, it might not work if it uses rawequals
instead of ==
.
EDIT: This also works:
print(a == {1, 2, 3})
print({1, 2, 3} == a)
but it won’t always work if one of the values has a different __eq metamethod defined, in that case I think it depends on which one comes first.
If you need to use a table as a key, use JSONEncode on it first!
local HttpService = game:GetService("HttpService")
local Key = HttpService:JSONEncode({"d", 12})
local K = {
[Key] = 6
}
print(K[Key])
-- or
-- print(K[HttpService:JSONEncode({"d", 12})]
Yes, but not in the way you’re doing it. Just because the table your indexing it with looks the same, doesn’t mean it’s the same.
local thing = {"d",12}
local thing2 = thing
print(thing == {"d",12}) --> false
print(thing == thing) --> true
print(thing == thing2) --> true
print({} == {}) --> false
thing
and thing2
are pointing to the same table, so the two variables are equal. Two tables that look alike aren’t always the same. I suggest using a 2D table like @ThanksRoBama said, or combine the two values in the key.
-- 2D Table:
local Data = {
d = {[5]=8},
g = {[2]=1},
}
-- Combined:
local Data = {
D5 = 6,
D8 = 8,
D12 = 2,
}