foreach in reverse

Hello there!

Is there a way to program a foreach in reverse?

Example:

	foreach(Transform myLayer in transform.InReverse())
	{
		// Deactivates the game object.
		myLayer.active = false;
		yield return 0;
	}

Notice that I put an InReverse() that exists in Arrays, however it doesn’t exist in the Transform.

Thanks!

I don’t know if this will work (untested, just stumbled upon it in the intellisense) but seems to make sense. If it doesn’t, then you’ll probably have to loop through it once and feed it into your own array, then reverse through that array in a similar fashion.

for (int i = this.transform.GetChildCount(); i >= 0; i--) 
{
    Transform childTransform = this.transform.GetChild(i);
}

foreach is used to traverse through sets when ordering is irrelevant. If you need ordered traversal, you should use a for (int …) loop.

I realize that you need this for traversing the children of a transform which can only be accessed using foreach (note that the GetChild function mentioned by Fizix is undocumented/deprecated). There is a reason you can only use foreach (the same reason GetChild is undocumented/deprecated): you should never rely on the ordering of the children. The ordering is simply not guaranteed to be consistent during the course of your application.

The proper way of doing this is to construct your own array, containing references to the child nodes you’re interested in. This array is under your own control, meaning the ordering is guaranteed as well.

Thanks for the input tomvds; I was wondering why I couldn’t find those methods in the Unity reference docs. :smile:

Thank you very much tomvds and FizixMan, I will enumerate the Transform Child and order them. That seems to be the best way I can think to solve this problem!

	IEnumerator DestroyOneByOne()
	{
		int counter = transform.childCount;
		myArray = new Transform[transform.childCount];
		foreach(Transform myLayer in transform)
		{
			int aux = int.Parse(myLayer.name);
			myArray[aux - 1] = myLayer;
		}
		
		for(int i = (counter-1); i >= 0; i--)
		{
			myArray[i].active = false;
			yield return new WaitForSeconds(fStep);
			yield return 0;
		}
	}

I know that this is not the most beautiful way to solve this problem, but it worked just fine!

I Know This is old, but you can achieve this this way:

using System.Linq;

public class ExampleClass : MonoBehaviour {

    public Object[] anyTypeArray;

    public void Start () {

        foreach(Object part in anyTypeArray.Reverse()) {
            //Insert your code Here
        }

    }

}

The IMPORTANT! part is to add this line at top:

using System.Linq;
1 Like

Use a for loop and set the iterator to the length of the array and cout down to zero.

for(var i = items.Length - 1; i >= 0; i--){
    var item = items[i];
}
2 Likes

I have had much success in Game Maker: Studio and Unity following this methodology:

 void Awake()
    {
        //The length you will need (Let's use a sample length of 3)
        var myLength = 3;

        //Number of loops to iterate (is a 2-d array in this case--will also work with a 1-d array)
        for (int i = 0; i < myLength; i++)
        {
            for (int j = 0; j < myLength; j++)
            {
                //Set inverse counters
                //NOTE: if the length 'i' was counting to is unique (like a jagged array), Use THAT length when obtaining the opposite counter for i. Sorry if that's not clear from this example.
                var l = myLength - i;
                var opp_i = Mathf.Abs((myLength - l) - ((l + i) - 1));
                //Likewise here, use the length associated with whatever j needs to count to.
                var p = myLength - j;
                var opp_j = Mathf.Abs((myLength - p) - ((p + j) - 1));

                //View results
                print("i = " + i);
                print("opp_i = " + opp_i);
                print("j = " + j);
                print("opp_j = " + opp_j);
            }
        }
    }

Console output sample:

As you can see, you get positive and negative counters at the same time. It’s really useful for resizing and filling 2D arrays (especially for rotating them). I’m sure you will find many uses.

In answer to your first question, I’m not sure how to iterate through a foreach loop in reverse. You would have to populate the generic List or array “backwards” first and then, when you use a foreach loop, it would iterate “backwards” because the indices would have been populated in reverse order. The easiest way to iterate in reverse dynamically might be to follow the above method in a for-loop.

It’s great that you’re trying to help, but this thread is 8 years old and was last posted in 2,5 years ago, so it might just be that the people you’re replying to have moved on with their lives.

1 Like

Peradventure, someone was searching the internets for a similar question, they’d be drawn here and my suggestion might help them. That is why you post to old threads sometimes.

2 Likes

Botcho, keep up the good work, thanks!

cool necro,
but @Botcho why you simply not use

// Reverse counting
for (int i = myLength; i > 0; i--)

Rather than supper over complicating?

They might have gone on with their lives, but noobs like me who are just learning, still find every single response useful and educational. I appreciate each and every person with more knowledge than I have, sacrificing their time and donating their talent so that I can learn. Even if something is deprecated, or is not best practice, I can still learn what not to do.

Not to mention the fact that C# does get updated, and there might be new solutions to old problems. EG the amazing new switch language in C# 8. I mean, it’s beautiful!!!

Thank you so much everybody!!

3 Likes