Looping through a Dictionary in order

I’m just working on a little side project for a few hours, and I’ve ended up confused :stuck_out_tongue:

I have a Dictionary of block rarities, as follows:

 local blockRarities = {[10000] = "Normal", [1000] = "Steel", [250] = "Magma", [50] = "Acid", [5] = "Emerald", [1] = "Tektite"}

And I’m looping through them, like this:

for key,val in next, blockRarities do
    -- do stuff
end

I always assumed that this would loop through starting with “Normal”, then “Steel” etc. And I’m pretty sure that’s how it has worked before on previous projects.
(EDIT: Apparently not lol)
If I print the Value when looping through, though, this is the output: Ignore the “not” I just printed it out weirdly… :stuck_out_tongue:

image

This is strange, so I thought perhaps it was because I was using a next loop, so I tried pairs and got the same result. Can someone explain to me why the code seems to loop through the Dictionary in such a random order? Is there some kind of logic here?? :laughing: Thanks!

1 Like

Dictionaries have no order. As well as this, the order of iteration when using next, t/pairs(t) is undefined. This is expected behaviour.

10 Likes

Weird. I’ve never noticed that before! Is it because of the way they are stored (in Binary) etc?

Yes. The order of arrays exist only through their integer keys (1, 2, 3, …, n).

1 Like

But if that’s the case, why do Tables/Arrays allow looping in order? Surely the Dictionary should then loop through in ascending order of key size/value, or am I confusing myself here?

If we have a table with ascending integer keys that have no gaps (known as an array), a, and an index, 3, we know that the next value of a is a[3 + 1].

If we have a table with something like string keys, we cannot simply increment the previous key to get the next. We, in fact, need to use the built-in next function. The function is used as next(t, lastKey), where t is the table and lastKey is the previous key of the table. The function returns the key and value of the next (with respect to lastKey) pair. The order of the elements that the function returns is undefined, so we cannot guarantee any specific order.

Fundamentally, it makes sense that dictionaries have no order. What should we use to order the following table?

local t = {
    [Vector3.new()] = true,
    ["hi"] = "bar",
    [9] = 123,
    [game] = "foo",
}
1 Like

Dictionaries are stored as hash maps. There is no order to the hashing algorithm.

Lua handles numeric keys differently and guarantees order as long as there are no gaps and it starts from 1.

7 Likes

Cool, thank you both for the help. Surprised I didn’t run into this before… Thanks again!

1 Like

Arrays also have no inherent order in Lua - the difference is that ipairs will traverse the gapless numeric keys starting at 1 in ascending order (pairs does not have this guarantee, even for arrays).

8 Likes

There is a way

Make A list

itemlist = {"ITEM1","ITEM2"}

itemdict = {"ITEM1"=20,"ITEM2"=30}

function getitem(list,dict)
      dict[list[-grab whatever-]]
end


1 Like