How the hell do I prevent a dictionary from rearranging into alphabetical order?

I am attempting to make a new game in which you run on segments. There are segment types, and they all have their own custom configuration and rarity.

In the dictionary, I make the segment types go from rarest to most common, so that it tries to take the rarest segment type possible and then go down until it selects a segment type

it kind of bothers me, because of the alphabetical order the way rarities work is pretty confusing, and one of the segment types even seems to barely generate anymore.

{
Example9 = {rarity = 20},
Example2 = {rarity = 1}
}

in this example, since it rearranges into alphabetical order, Example2 will be the first one at the top. However, its rarity is of 1, so Example9 cannot generate

Tables are not ordered dictionaries,

You can define your own order with a bit of structure using arrays for keys or sorting logic.

local segs = {
	Example9 = {rarity = 20},
	Example2 = {rarity = 1}
}

local order = {"Example9","Example2"}

for _, key in ipairs(order) do
	local seg = segs[key]
	print(key, seg.rarity)
end

Then there is always table.sort, but you’ll need a numeric-indexed array for that.

local segs = {
	{name = "Example9", rarity = 20},
	{name = "Example2", rarity = 1}
}

table.sort(segs, function(a, b)
	return a.rarity > b.rarity
end)

for _, seg in ipairs(segs) do
	print(seg.name, seg.rarity)
end
1 Like

If you want order for your data you’re using the wrong data type. Instead you need to use an array which is a data type that maintains order based on how you add elements to it(for example the element you add last through table.insert remains last until you add a new element through that method).

Adding to the above reply, if the table remains small, you can simply use the lazy way of doing things when trying to search something by a specific property(for example name):

local function getElementByName(name: string): {name: string, rarity: number}?
	for _, v in pairs(segs) do if v.name == name then return v end end
	return nil
end

However, if you plan to use this for large arrays(for example for arrays with more than 1000 elements), it’s better if you always keep the table sorted by the property you want to be searchable(in this case name) and every time you want to add a new element, instead of adding it to the last position, you do binary search to figure out where to add it, so the table remains sorted(instead of calling table.sort on the entire table each time).

In general situations where you have to use programming knowledge to solve something(for example a specific algorithm) instead of doing it the lazy way(such as looping over in this case) tend to arise when data scales up(for example the amount of elements increases).

I think you are confused on the sorting order of different types of tables.

In Luau, there are two types of tables, mainly arrays and dictionaries. Arrays, like what @NyrionDev has said, are order-specific, meaning each element in this table type are fixed at specific locations. When you iterate this table type, it always returns the element in th order in which they are defined in the table. For instance, iterating a table like so:

local t ={"Memes", "Roblox", "Spaghetti", "Dr. Dre"}

should return "Memes", followed by "Roblox" and so on.

Dictionaries, on the other hand, are key-specific, meaning each element can only be indexed or represented by a key in terms of their position in the table. Since it is not order-specific, the iterator function which iterates this table will return key-value pairs in random orders. For instance, iterating a table as shown below

local t = {
    Memes = "Roblox",
    Spaghetti = "Dr. Dre",
    Death = "Ooops",
}

might NOT necessarily return the key-value pairs in the order which you specified them. In other words, the first key-value pair you get might not necessarily be “Memes” and “Roblox”, instead it could be the other 2 key-value pairs.

So to answer your question, I suggeset that for each value of a key, you make another table, and in that table include the rarirty property along with other stuff you want to be added. Then when you want to find the value from the rarest to the most common, compare each iterated rarity with the previous iterated rarity.

local t = {
    Example9 = {
        rarity = 20,
        ...
    },
    Example2 = {
        rarity = 1,
        ...
    },
    ...
}

alright, that’ll work. Thank you!

yeah, I mostly already know, however I just wanted to be able to determine the order of a dictionary key, and not use arrays. Thank you tho!

I do know the difference between arrays and dictionaries, and I just wanted that dictionary, thanks for explaining however, I did learn some extra stuff! Thank you!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.