Table in loop executes backwards

For example, I have a table: {[4]=“value”,[5]=“value”,[6]=“value”} and when I execute for i, v in (this table) the loop executes backwards, not from 4 to 6 but from 6 to 4. Adding pairs does not change anything and ipars returns nothing. How can I make it always execute from the smallest index to the largest or in the order in which it is written in the table?

It should already do that, im guessing you have your highest table indexes are at the beginning of the table, that’s why its going first, you can remove the indexes, as Lua automatically assigns number indexes to each element, or use table.sort.

it isnt i just tried it myself and its going backwards :skull:

changing the numbers does weird things tho

I guess try removing the indexes, or sorting the table, did you try them out?

i did table sort it didnt change anything

i changed the numbers and its going
3
1
2
instead of
3
2
1

or
1
2
3

that’s not how table.sort works, its a function, with 2 parameters, a and b, depending on which one you compare, it will go back or forward.

local tbl = {1, 2, 3}

table.sort(tbl, function(a, b)
	return a < b
end)

for _,v in pairs(tbl) do
	print(v)
end

--Prints 1 2 3

or

local tbl = {1, 2, 3}

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

for _,v in pairs(tbl) do
	print(v)
end

--Prints 3 2 1


it is still printing the same thing

have you tried both of my snippets? swap around the <

nope nothing changed

try this out:

local tbl = {[2] = "this is number 1", [5] = "this is number 2", [23] = "this is number 3"}

local keys = {}
for k in pairs(tbl) do
	table.insert(keys, k)
end

table.sort(keys, function(a, b)
	return a < b
end)

for _,key in pairs(keys) do
	print(tbl[key])
end

1 Like

This is to do with the way Luau handles arrays and non-array numerical indexes as well as dictionaries.

Let’s take an array:

local array = {"one", "two", "three"}

It’s treated as this format:

local array = {
    [1] = "one",
    [2] = "two",
    [3] = "three"
}

correct? great.


Now, let’s take a dictionary. These are much different. For example, when you iterate over them, it does not iterate in order. You also can’t use ipairs on them, nor can you get the length of them (returns 0).

local tbl = {
	["key1"] = 1,
	["key2"] = 2,
	["key3"] = 3
}

print(#tbl) --> 0

for k, v in tbl do
	print(k, v)
end

--[[
this iteration gave me this order:
key1 1
key3 3
key2 2
]]

When Luau looks for an array, it looks for consecutive numerical indexes ascending from 1. A break in this with numerical indexes will from then be treated as a dictionary, which relates to the error “Using ‘#’ (the length operator) on a table without an array part is likely a bug”. Keyword part, indicating sections of tables can be treated differently.

When applied to this table, the numerical indexes, while they are consecutive, do not start at one (as you commented that part of the code out). Luau will then treat this like a dictionary; using # will return 0, and iteration will not be in order.

local tbl = {
	[4] = 1,
	[2] = 2,
	[3] = 3
}

print(#tbl) --> 0

for k, v in tbl do
	print(k, v)
end
--[[
this iteration gave me the order:
3 3
2 2
4 1
]]

Therefore, table.sort also will not fix this issue as you cannot sort dictionaries. In summary, there isn’t anything you can do without a massive workaround to fix this issue apart from changing the numerical indexes to consecutive ascending integers starting from 1.


The reason @JAcoboiskaka1121’s workaround worked because it uses an array table of the keys and then iterates over that, reading keys in the desired order. Therefore, it bypasses this behaviour of dictionaries.

3 Likes

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