Thank you so much! But I still have a lot of dictionaries that have to be converted into an array of dictionaries. Are you kind enough to help me out a bit please? Here is an example:
Don’t convert it to an array, just use this function…
module.healths = {
["100"] = 5000;
["110"] = 15000;
["120"] = 35000;
["130"] = 50000;
["145"] = 75000;
["160"] = 125000;
["185"] = 300000;
["200"] = 475000;
["225"] = 750000;
["255"] = 1050000;
["280"] = 1350000;
["320"] = 1850000;
...
}
local function getKeys(t)
local keys = {}
for k in next, t do
table.insert(keys, k)
end
table.sort(keys)
return keys
end
for _, k in ipairs(getKeys(module.healths)) do
local v = module.healths[k]
print(k, v)
end
you might be wondering, why doesn’t this work with all dictionaries?
well the function sorts alphanumerically, this means that it will work if the number keys are in order or if the text is in alphabetical order
you also can’t have a string and a number as a key in the same table, this is because you can’t compare string and number
anyways since it sorts alphanumerically stuff like this also won’t work right
I slightly modified a code sample I wrote a few months ago, for your specific situation:
local dictionary = { -- the dictionary in question to be looped through
-- these are example values to be sorted properly
['110'] = 100011001,
['105'] = 20293922,
['230'] = 923929932,
['c'] = 292382,
['a'] = 29382393128,
}
local function loopDictionaryInOrder(dict, func)
local data = {} -- array to hold the indexes
for key, value in pairs(dict) do -- loops though the dictionary provided in the first parameter
table.insert(data, key) -- this adds each key to the 'data' array
end
table.sort(data, function(a, b) -- this sorts the data array by each key's byte (numeric representations)
local toNumA = tonumber(a)
local toNumB = tonumber(b)
if toNumA and toNumB then
-- this checks for 2 integer values and sorts them accordingly
return toNumA < toNumB
end
return tostring(a):lower():byte() < tostring(b):lower():byte()
end)
for _, key in ipairs(data) do
-- loops through the 'data' array and calls the function provided in the second parameter
-- the function gives the key as the first argument and the key's value as the second argument
func(key, dict[key])
end
end
-- this is an example usage of the function
loopDictionaryInOrder(dictionary, function(key, value)
-- print each key and value in order
print(key, value)
end)
I can’t see if this works in Roblox Studio because Roblox is down at the moment, but it works on Lua’s Demo Site.
The regular sort provides the same result in this case.
You could also use the function as an iterator function, which I think is pretty cool:
local function idict(t)
local keys = {}
for k in next, t do
table.insert(keys, k)
end
table.sort(keys)
return function(_, i)
i += 1
local k = keys[i]
if k then
return i, k, t[k]
end
end, keys, 0
end
for _, k, v in idict(module.healths) do
print(k, v)
end
Thank you very much for all your replies! I should have edited the title, but what I actually want is a function that returns the next index of the given index. Can someone help me with making a function that returns the next index of a given index please? Like for example,
module.NextHealth = function(currentHealth)
-- current health is 145
-- I want to get 160 because it is the next index
-- if currentHealth is already the last index, return the string "MAX"
end
local nextIndex, nextValue = next(table, currentIndex)
Bear in mind, as I’ve mentioned, that dictionaries don’t really have an order. I think this method does work on arrays and in order, but if it doesn’t then this is all you need.
local function arrayNext(tab, key)
return key+1, tab[key+1] or "MAX"
end
Its worh noting that Lua cannot guarantee the order of a dictionary that doesn’t have a numeric key sequence. ipairs internally runs through an array from 1 until it hits a nil value.
Since dictionaries dont have a numeric key sequence, it simply cannot work. The only way to do this is to sort the dictionary into a list of key value pairs yourself by passing through it, then ipairs it {["110"] = "metatablecatgirl"} -> {[1] = {Key = "110", Value = "metatablecatgirl"}}
I mean that’s literally the code I gave.
If you want to get the next index and value in a dictionary you can use this
local nextIndex, nextValue = next(table, currentIndex)
So by way of example
local example = {Boat = "Red", Car = "Blue", Truck = "Green"}
local nextIndex, nextValue = next(example, "Car")
print(nextIndex)
print(nextValue)
This will print the index and value after the index “Car”. I really don’t think this is what you want though since you seem to want your dictionary to be ordered. I think you need to refer to my first post in this thread.
module.healths = {
["100"] = 5000;
["110"] = 15000;
["120"] = 35000;
["130"] = 50000;
["145"] = 75000;
["160"] = 125000;
["185"] = 300000;
["200"] = 475000;
["225"] = 750000;
["255"] = 1050000;
["280"] = 1350000;
["320"] = 1850000;
}
module.healthsIndex = {}
for key, value in pairs(module.healths) do
module.healthsIndex[#module.healthsIndex+1] = key
end
table.sort(module.healthsIndex, function(a, b) return module.healths[a] < module.healths[b] end) -- Sort by value rather than key
module.healthsNext = function(key)
local index = table.find(module.healthsIndex, key)
if index then
local newKey = module.healthsIndex[index+1]
if key then return newKey, module.healths[newKey]
else return "NaN", "MAX" end -- If there is nothing larger, return the key NaN and the value MAX
else
warn(("Unable to find key \"%s\" in module.healthsIndex"):format(key))
end
end
print(module.healthsNext("120")) --> 130, 50000
wow thank you so much bro i never new it was that easy!!! Sorry for the confusion but i never knew about the next() function so I made a REALLY COMPLICATED way of using an odered loop to get the next index thanks
Oh shoot I forgot. I kept thinking table.insert was slower just because it shifted all the table entries when you inserted in the middle of the table. But it’s written in C innit?
you should be able to find that quote under performance improvements
I had to quote it like this because the topic is closed and I can’t exactly quote it from there so a hyperlink will work