Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing Foreach Order?

Tags:

c#

foreach

Is there anyway to foreach through a list from the end to the beginning rather than the beginning to then end (preferably without reordering the list).

like image 205
sooprise Avatar asked Jul 23 '10 17:07

sooprise


People also ask

Does forEach go in order?

Calls the given closure on each element in the sequence in the same order as a for - in loop.

Why is forEach forward only?

That is because foreach is meant to iterate over a container, making sure each item is visited exactly once, without changing the container, to avoid nasty side effects.

Does forEach maintain order in Java?

The behavior of forEach() operation is explicitly non-deterministic. For parallel streams, forEach() operation does not guarantee to respect the encounter order of the Stream. While the forEachOrdered() operation respects the encounter order of the stream if the stream has a defined encounter order.

Which is faster forEach or for?

As it turned out, FOREACH is faster on arrays than FOR with length chasing. On list structures, FOREACH is slower than FOR. The code looks better when using FOREACH, and modern processors allow using it. However, if you need to highly optimize your codebase, it is better to use FOR.


3 Answers

IList<String> strList = new IList<String>();
strList.Add("A");
strList.Add("B");
strList.Add("C");

for (int i = strList.Count-1; i>=0;i--)
{
    Console.WriteLine(strList[i]);
}

not tried but should work.

like image 32
Tiju John Avatar answered Oct 12 '22 23:10

Tiju John


Error checking ommitted for clarity. Use a custom implementation of IEnumerable and IEnumerator. This will avoid unnecessary copying.

using System;
using System.Collections.Generic;

namespace ConsoleApplication3
{
    class ReversedEnumerator : IEnumerator<int>
    {
        List<int> v;
        int index;

        public ReversedEnumerator(List<int> v) {
            this.v = v;
            this.index = v.Count;
        }

        public int Current
        {
            get { return v[index]; }
        }

        public void Dispose()
        {
        }

        object System.Collections.IEnumerator.Current
        {
            get { return v[index]; }
        }

        public bool MoveNext()
        {
            return --index >= 0;
        }

        public void Reset()
        {
            index = this.v.Count;
        }
    }

    class EnumeratorStub : IEnumerable<int>
    {
        List<int> v;

        public EnumeratorStub(List<int> v)
        {
            this.v = v;
        }

        public IEnumerator<int> GetEnumerator()
        {
            return new ReversedEnumerator(v);
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return new ReversedEnumerator(v);
        }

    }

    class Program
    {
        static EnumeratorStub Reverse(List<int> v)
        {
            return new EnumeratorStub(v);
        }

        static void Main(string[] args)
        {
            List<int> v = new List<int>();
            v.Add(1);
            v.Add(2);
            v.Add(3);

            foreach (int item in Reverse(v))
            {
                Console.WriteLine(item);
            }

            Console.ReadKey();
        }
    }
}

I would recommend to refactor the code sample to use generics. That way you could use this for any container type.

like image 30
Jorge Ferreira Avatar answered Oct 12 '22 23:10

Jorge Ferreira


using System.Linq;

foreach(var item in source.Reverse())
{
    ...
}

Edit: There is one more step if you are dealing specifically with a List<T>. That class defines its own Reverse method whose signature is not the same as the Enumerable.Reverse extension method. In that case, you need to "lift" the variable reference to IEnumerable<T>:

using System.Linq;

foreach(var item in list.AsEnumerable().Reverse())
{
    ...
}
like image 96
Bryan Watts Avatar answered Oct 12 '22 23:10

Bryan Watts