Ordering data in a module script

I am trying to make a pet system which requires a module script which has the pet rarities, I used math.random to choose a number between 1-100, the system uses a for i,v in pairs loop to loop through the rarities table and check which rarity the random number lies in.

However, the problem is, when I loop through the module script’s table, it doesn’t go through the data from top to bottom in an orderly fashion, however it loops through the indexes randomly, which, in my code, prevents the pet system from working properly.

I have tried asking some friends who have experience in programming, but I am still awaiting response, I have also tried looking up the developer page to check if I am doing something wrong or not. I have also tried searching for a devforum topic which addresses a similar issue, but found nothing.

Any sort of help will be very much appreciated! :smiley:

You can run a numerical for loop, which will always go in order.

`for i = 1, #TABLE do
    local v = TABLE[i];
    -- Do what you want with v.
 end 
 `

use ipairs instead of pairs for your loop

1 Like

IPairs? What is that? Is that some sort of loop which loops through a table from top to bottom?

ipairs iterates through the array in order, but it does not work on dictionaries. ipairs will stop once it reaches a nil value.

How come it doesn’t work on dictionaries? Also can you please link a developer article on ipairs?

ipairs iterates over numerical indexes, and dictionaries have string indexes most of the time.

Here is a link to the page on ipairs.

So what should I do? In my case I need to iterate through a dictionary in order.

I could try that, but is there really not a better solution?

You cannot iterate through a dictionary in an order because dictionaries do not have an order. Not even in the order it’s written in in the code.

You’d have to write the pet rarities in an array ({Pet1, Pet2} etc.) to loop through them in a consistent order. If you need them to be in a dictionary, then it doesn’t take more than 10 lines of code to loop over that array and put them in a separate dictionary.

If this doesn’t help you, then you should tell us how your dictionary is set up and how you are looking for the chosen rarity. What are they key and the value in the dictionary? [Pet object in ServerStorage] = Rarity? Something else?

Here is an example of what is in it:

{
Bee = 20;
Turkey = 40
}
etc.

Yeah, that was what I thought at first.
You ought to put an order to it somehow. There are a few ways-

Table for each pet

You change the table to this:

{
	{Name = "Bee"           ;Rarity = 20};
	{Name = "Turkey"        ;Rarity = 40};
}

(leaving spaces to align the rarity and moving the ; doesn’t make it work better, just looks nicer that way)
Now you can use ipairs or a numeric for loop or just continue using pairs to loop over the data. The v of your "i,v pairs loop will just be another table, you will need to get v.Name or v.Rarity for what you need.
The downside is that there’s a bunch more little quotes and curly braces to write than before.
But this is sort of the right way to do it. You not only get an ordering, but can easily add more properties to the pets, like price, favorite color etc. (unless there’s some other module with that info)
So any examples following this are going to be kind of stupid.

Interleaved name and rarity

local pets = {
	"Bee", 20;
	"Turkey", 40;
}
for i = 1, #pets, 2 do -- loop over the table, skipping second, fourth, sixth etc. thing
	local name = pets[i]
	local rarity = pets[i+1]
	-- ...
end

Metatable

local pets = setmetatable({}, {__newindex = function(tbl, key, value)
	-- whenever pets.%Name% = %Rarity% is done, instead insert {Name = %Name%; Rarity = %Rarity%}
	rawset(tbl, #tbl+1, {Name = key, Rarity = value})
end})
pets.Bee = 20
pets.Turkey = 40
-- result is the exact same table as in the first example

This is stupid and 10x slower, but also a way to do it.

“Now I can’t do pets[name] to get the rarity, what gives?”

Make a new, separate table. Loop over the pets table, and set newPets[name] = rarity. You now have the same table that you posted and that goes in a random order with pairs, but also a different table (by me) that has an order.

1 Like