How to use ipairs on dictionaries

Simple: I need the to loop through a dictionary in the sorted order. Please reply. Any help is appreciated. Thank you so much!!

1 Like

you could make a separate table for the keys

local Table = {
    Keys = {
        "One",
        "Two",
        "Three"
    },
    One = 1,
    Two = 2,
    Three = 3
}

for Key, Value in ipairs(Table.Keys) do
    Key = Value
    Value = Table[Value]

    print(Key, Value)
end

this way it would go in order

1 Like

Pairs is what you need to iterate over a dictionary, not ipairs. But dictionaries don’t have any order or sort to them, and the only way to sort one is to keep a separate array of keys in the dictionary.

local dict = {car = 5, truck = 30, bus = 14}
local array = {"car", "truck", "bus"}

Here you would sort array and use it to get the elements of the dictionary.

table.sort(array, function(a, b) return dict[a] > dict[b] end)
print(dict[array[1]])
3 Likes

Thank you, but I don’t want to convert them all manually because I am using a dictionary for a Health upgrade. And it is going to be big. Here is a part of it:

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;
    ...
}

As you can see, the reason I can’t use math is because I don’t want it to always only add 10 to the cost, which is the index. Is there another way of doing it? THank you!

Thank you, but I don’t want to add so much repeated codes all manually because I am using a dictionary for a Health upgrade. And it is going to be big. Here is a part of it:

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;
    ...
}

As you can see, the reason I can’t use math is because I don’t want it to always only add 10 to the cost, which is the index. Is there another way of doing it without repeating codes? Thank you!

module.healths = {
    {
        Health = 100,
        Cost = 5000
    },
    {
        Health = 110,
        Cost = 15000
    },
    {
        Health = 120,
        Cost = 35000
    },
    {
        Health = 130,
        Cost = 50000
    },
    {
        Health = 145,
        Cost = 75000
    },
    ...
}

for _, Data in ipairs(module.healths) do
    print(Data.Health, Data.Cost)
end

why not do it like this?
also I think I got the Health and Cost right, could be mixed up though

1 Like

Thanks, but it doesn’t iterate in order tho… If it does, can you show me the loop? THx

module.healths = {
    {Health = 100, Cost = 5000},
    {Health = 110, Cost = 15000},
    {Health = 120, Cost = 35000},
    {Health = 130, Cost = 50000},
    {Health = 145, Cost = 75000},
    ...
}

for _, Data in ipairs(module.healths) do
    print(Data.Health, Data.Cost)
end

you could also shorten the table if you want, this would save space compared to the other code I sent

ok let me try it

character limit

the for loop is all the way at the bottom, it should go in order

what I actually want is, for example, i have the index and the value of one of the line, say
health = 120, cost = 35000
i want to get the next index so i would get 130. Do you know how to get (130) from (120) or get (130) from (35000) ?
EDIT: I want to be able to do this without adding repeated codes. In my previous game i had another whole dictionary that basically has the next index. But that is WAY too complicated. Thank you so much for helping please give me a solution thx

module.healths = {
    {Health = 100, Cost = 5000},
    {Health = 110, Cost = 15000},
    {Health = 120, Cost = 35000},
    {Health = 130, Cost = 50000},
    {Health = 145, Cost = 75000},
    ...
}

function NextHealth(Data)
    return module.healths[table.find(module.healths, Data) + 1] or {Health = nil, Cost = nil}
end

for _, Data in ipairs(module.healths) do
    local NextData = NextHealth(Data)

    print({
        Old = {Data.Health, Data.Cost},
        New = {NextData.Health, NextData.Cost}
    })
end

is this what you want?

EDIT:
fixed a bug
also I edited the printing a bit

Oh yes thank you so much!! I didn’t know about table.find(). Thanks! :slight_smile:

Wait is there a way without change it into table of dictionaries? Like keep the original:

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;
    ...
}

And then add some code like table.find and stuff

Dictionaries have no order, there is no way to go through them in order in that format without any of the solutions other people have listed above, sorry

Use @D0RYU’s solution. That will work perfectly in your case

2 Likes

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? To contact me, you can join my discord server here. Thank you so much again! :slight_smile: Have a nice day!

Numbers are sorted automatically (from lowest to highest), you can simply do this and use pairs:

local Dict = {
	[1] = { Health = 100, Cost = 5000 },
	[2] = { Health = 100, Cost = 5000 },
	[3] = { Health = 100, Cost = 5000 },
}

for Index, Value in pairs(Dict) do
	print(('Index: %d, health: %d, cost: %d'):format(Index, Value.Health, Value.Cost))
end

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:

Turn this:

    ["100"] = 5000;
    ["110"] = 15000;
    ["120"] = 35000;
    ["130"] = 50000;
    ["145"] = 75000;
    ["160"] = 125000;
    ["185"] = 300000;
    ["200"] = 475000;
    ["225"] = 750000;
    ["255"] = 1050000;
    ["280"] = 1350000;
    ["320"] = 1850000;
    ["350"] = "MAX";

Into this:

    {Health = 100, Cost = 5000},
    {Health = 110, Cost = 15000},
    {Health = 120, Cost = 35000},
    {Health = 130, Cost = 50000},
    {Health = 145, Cost = 75000},
    {Health = 160, Cost = 125000},
    {Health = 185, Cost = 300000},
    {Health = 200, Cost = 475000},
    {Health = 225, Cost = 750000},
    {Health = 255, Cost = 1050000},
    {Health = 280, Cost = 1350000},
    {Health = 320, Cost = 1050000},
    {Health = 225, Cost = 1850000},
    {Health = 350, Cost = "MAX"},

Can you help me please? If you are kind enough, I can send you all my codes :slight_smile:

Thank you so much again! :slight_smile: Have a nice day!

You can run this in find/replace with regex enabled:
find:
\[\"(.+)\"\] ?= ?(.+);
replace:
{Health = $1, Cost = $2},

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
5 Likes