Built-in backwards table iteration in for loops

Currently, if we want to iterate backwards through a table we would do something like this:

for i = #t, 1, -1 do
	local index = t[i]
	-- code
end

Whereas if we want to iterate forwards through a table, we can do something like this:

for index, value in ipairs(t) do
	-- code
end

Because of the nature of Roblox lua, we are limited in the speeds of our methods. That is to say, built-in methods are noticeably faster than custom methods. What I am proposing is the introduction of a method named ipairs2() which acts similar to the method named ipairs(), except that ipairs2() will iterate backwards through the table, instead of forwards. Not only would this provide a noticeable increase in speed, it would also make it far easier to use backwards table iteration.

This can be accomplished in Roblox lua currently, at the expense of being ~5-10x slower by doing something like this:

local function ipairs2(a, i)
	i = i and i - 1 or #a
	local v = a[i]
	if v then
		return i, v
	end
end

You can then call this as follows:

for index, value in ipairs2(t) do
	-- code
end

Now, what use does this have? If you have ever had to include a j or offset variable in your for loop to account for objects being removed from a table, you should be using backwards iteration instead because it doesn’t care if something is removed at a given index, because it starts from the end and goes to the beginning. What this means is that you can remove an unnecessary variable from your code by using backwards table iteration.

If Roblox is able to address this issue, it would improve my development experience because it would make backwards table iteration easier to use, and noticeably faster.

5 Likes

Your proposal is for iterating arrays, but your examples use next, which is for iterating dictionaries. Dictionaries are order-less, so it’d be clearer if you specified that what you actually want is an inverse to ipairs.

4 Likes

You are correct, I misunderstood the usage of next as that which is used to iterate through arrays with a specific index. Although it can seemingly be used for iterating through arrays, as you said ipairs is far better for this and an inverse of ipairs is what I was looking for.

I will be adjusting the topic to better reflect this.

1 Like

Out of curiosity why do you want to iterate backwards over such a large table?

2 Likes

There are multiple reasons why someone wants to iterate backwards. For example, if they are destroying some of the items as they go (which will mess up the loop if you’re going forwards), or, if they want the last objects (sorted however they are currently sorted) to have an action performed first.

There still seems to be no efficient way to do this.

Although I think it should be called ipairsRev rather than ipairs2…

Instead of creating a new function, id rather have another argument for ipairs() and pairs() for backwards iteration it should be a boolean. Currently i need to modify the behavior of __iter but it applies to every single one in the code, so a new paramter is necessary.

I would really love to has this added due to the problems being stated above that am also currently facing. For the naming, we can use the name reversed like python do, or the ones suggested above.

1 Like