Why is the pairs loop not going in order in my module?

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!

I am attempting to make a function that automatically creates my 100+ weapon UI boxes since I dont want to manually do it. It shows only a little bit of them in the module as a test.

  1. What is the issue? Include screenshots / videos if possible!

I get no error and it creates the buttons fine but they are not in order they were set in the module such as default sword being third and solar sword being first while the default sword is first inside the module.

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

I thought it was a delay of the UI not loading in fast enough for the buttons but even I simply print out the names they are out of order. I cant find any answers.

here is my module

local Swords = {
["Default Sword"]={Gain=2,Price=0, Type = "Sword"},
["Fire Sword"]={Gain=3,Price=29, Type = "Sword"},
["Grass Sword"]={Gain=5,Price=50, Type = "Sword"},
["Bolt Sword"]={Gain=8,Price=87, Type = "Sword"},
["Doom Sword"]={Gain=13,Price=151, Type = "Sword"},
["Ocean Sword"]={Gain=21,Price=262, Type = "Sword"},
["Night Sword"]={Gain=34,Price=455, Type = "Sword"},
["Solar Sword"]={Gain=55,Price=789, Type = "Sword"},
["Shock Sword"]={Gain=89,Price=1369, Type = "Sword"},
["Thunder Sword"]={Gain=144,Price=2374, Type = "Sword"},
}

return Swords

here is my loop function. Note this is not the full code as my full UI script has 400+ lines of code but the variables for the module are correct.

for k,v in pairs(WeaponInfo) do
	local Template = WeaponButtonTemplate:Clone()
	Template.Parent = ShopUI.Main.WeaponScrollingShop
	Template.Name = k
	Template.Gain.Value = v.Gain
	Template.Price.Value = v.Price
	Template.WeaponType.Value = v.Type
end
1 Like

pairs does not get the table in the same order it was defined but in any order, and there is no way to get a dictionary in a set order, if you wish to get the table in the defined order you can only use arrays with an ipairs loop like:

for k,v in ipairs(WeaponInfo) do

end

Your going to have to reformat your table into an array though like this:

local Swords = {
[1] = {Name = "Default Sword", Gain=2,Price=0, Type = "Sword"}
}

You could also make your own custom iterator that returns the items based on the price, but that will be more complicated than just using a array.

4 Likes

thanks for the tip :grin:

30 chars

There is a difference between [1] = x, [2] = y, [3] = z, etc.

image

So it is better to just do { "a", "b", "c" }

how would I loop through it then?

your not using a ipairs loop , thats why

But it should have gone in order anyway even if order isn’t guaranteed.

I just tested it with ipairs and it worked correctly.

That is fine

1 Like

Pairs:

function , table pairs ( table t )

IPairs:

function , array , int ipairs ( array t )

Yeah, it’s weird, but for reasons probably having to do with being able to optimize performance when order isn’t necessary, pairs(), and the next iterator on which it’s based are defined by the Lua standard as returning keys in arbitrary order. So when using next, there is no “should be in order anyways” even for the array part of the table. It’s only robust, portable Lua if you make no assumptions about the iteration order of next.

1 Like

Yeah I see. I just find it weird when

for i in pairs({ [1] = "a", [2] = "b", [3] = "c" }) do
    print(i)
end

doesn’t go in order but

for i in pairs({ "a", "b", "c" }) do
    print(i)
end

does. I do see why we shouldn’t be relying on that order though

Oh yes, it’s definitely weird as well as a common pitfall for developers coming to Lua from pretty much any other language. But, I’m sure it was not an arbitrary decision on the part of the Lua standards makers. I’d be willing to bet they had something in mind like: “let’s have ipairs for when order needs to be preserved, possibly at the expense of some overhead or less-than-optimal memory access order needed to guarantee it, and let VM implementors optimize pairs however they want, so they’re free to do something like fetch keys in the fastest order possible, even if it means iterating the array part in what might seem like random order to the Lua scripter.”

I think if you look at it that way, you can see how it would make pairs more flexible than just having it be a superset of ipairs.