Currently table.find does not work with dictionaries. If I have a value and want to find its key in a dictionary, I have to manually iterate over the dictionary and compare the values until one is found. table.find was added to make doing this easier with tables, it should also work with dictionaries
local Values = {"a", "b", "c", "d", "e"}
print(table.find(Values, "d")) -- 4
local Values = {["key1"] = "a", ["key2"] = "b", ["key3"] = "c", ["key4"] = "d", ["key5"] = "e"}
print(table.find(Values, "d")) -- nil, desired value is "key4"
table.find was designed for arrays. I donât see why table.find should support dictionaries. There is no way to know which occurrence of the value youâre looking for is found.
table.find is used so much, and it might break some scripts by adding this functionality. I still want this feature, so maybe add it a different way?
local data = {
Equipped1 = "Apple",
Equipped2 = "Medkit",
Equipped3 = "Burger",
Equipped4 = nil,
}
if (method here) and humanoid.Health < 50 then
print("Maybe you should heal?")
end
-- Methods:
"Medkit" in data
"Medkit" not in data
table.has(data, "Medkit")
table.contains(data, "Medkit")
table.find(table.values(data), "Medkit")
This does make sense because tables donât have a specified order, but Iâm not sure if it matters very often which one you get. They could make it behave like ânextâ does if we needed to find all of them.
local t= {a = 10, b = 5, c = 10, d = 10}
print(table.find(t, 10)) --> a
print(table.find(t, 10, a)) --> c
But this requires modifications to the parameters and an extension of the current behavior.
I think it may be more beneficial to add a new set of C-based dictionary functions. Honestly Iâm surprised we donât have these already, since the need is so common to count the elements in a dictionary with a crummy Lua for loop.
examples
print(dict.count(t)) --> 4
dict.find(t, 10) --> a
local keys = dict.keys(t)
table.sort(keys)
for key in keys do
print(dict[key]) --> 10 5 10 10
end
-- we could even get some 'convenience' functions such as these
for key, value in dict.values_sorted(t) do
print(value) --> 5 10 10 10
end
for key in dict.find_all(t, 10) do
print(key) --> a c d
end
Itâs not even just find, the majority of the table standard library is designed for use with the array portion of tables. Developers have always had to create their own libraries for further dictionary tooling. OP should use open source libraries like sift which supports dictionary tooling.
I donât think thereâs anything wrong with iterating over the dictionary and comparing values or making a reusable parametrised function to avoid repeating the same âmanual iterationâ code. Youâre still just calling a single function, just that itâs not available as a global.
Agree with the above though. If it has to be a thing, would prefer a Roblox standard library or explicit methods that, by design, work with the hash portion of tables. Overriding is strange.
The table library is designed to work with arrays, not dictionaries. Now, Iâm not saying that this feature request is invalid in any form, but it would be inconsistent throughout the libraryâs design. Additionally, what if something like this exists:
local myUnorganizedTableThing = {
StringIndex = workspace.Bighead2,
[646511225] = "i_am_admin",
Vector3.new(4,7,78) = workspace.SpawnLocation,
65,
"tablestuff",
[4] = 'i am not replacing 4th index right?',
[print] = {"i print for you, don't forget about me. im low on ink btw", InkLevel = .094}
}
table.find just wouldnât work here. It would break a lot of code if it suddenly started returning functions stored as the index in these abominations unique tables.
However, if we forget about backwards compatibility and consistency for a second, it does seem like a good addition. It should be implemented through a different library or a function of a different name. It would technically be the reverse of the __index metamethod, which we should also get.
It would be a nice feature but there are other options out there as @colbert2677 said. The table library is also primarily for arrays so it wouldnât make sense to have a dictionary-specific function in there.
If youâre talking about having one function that can loop through both then itâs just easier to use an OSS tool.
Personally, I do not see why the table module meant for tables should have arbitrary support for dictionaries when the solution to finding keys is as easy as defining a function.
Although yes, defining it all the time is annoying and it has flaws (such as only working with dictionaries that have unique values⌠which is rare), so I do totally agree that there should be a way to find the keys from a dictionary value.
If a value does not exist in a table, it will be nil, so the code can be shortened to:
local function find<a>(haystack: {[any]: a}, needle: a)
return haystack[needle]
end
You donât need a function for this, it will only made code slower and harder to read:
local A = find(MyTable, MyKey) -- Bad
-- vs
local A = MyTable[MyKey] -- Good
This is not what the feature request is asking for. You are effectively saying that table.find is just Haystack[Needle], which it quite obviously isnât. table.find is actually:
function table.find(Haystack, Needle)
for NeedleIndex, PossibleNeedle in Haystack do
if PossibleNeedle == Needle then
return NeedleIndex
end
end
return nil
end
(NOTE: table.find in implemented in C++ and is not programmed exactly like that, but they give the same result.)
So, what the feature request is asking for is the above to work for dictionaries:
-- This is an array
local Sites = {
"devforum.roblox.com",
"create.roblox.com",
"www.roblox.com"
}
-- To get "create.roblox.com", you do this:
local CreatorSite = Sites[2]
-- Sites[2] gets the second entry in the array
-- This is a dictionary
local Sites = {
DevForum = "devforum.roblox.com",
CreatorSite = "create.roblox.com",
MainSite = "www.roblox.com"
}
-- Now, to get create.roblox.com you do this instead:
local CreatorSite = Sites.CreatorSite
-- Sites.CreatorSite looks for the entry in the dictionary with "CreatorSite"
-- before it, which is it's "key".
Because, table.finddoesnât work for dictionaries, and this feature request is requesting that it is updated so it can.