Possible to iterate backwards through a foreach?

前端 未结 11 2128
无人及你
无人及你 2020-11-27 03:54

I know I could use a for statement and achieve the same effect, but can I loop backwards through a foreach loop in C#?

相关标签:
11条回答
  • 2020-11-27 04:27

    As 280Z28 says, for an IList<T> you can just use the index. You could hide this in an extension method:

    public static IEnumerable<T> FastReverse<T>(this IList<T> items)
    {
        for (int i = items.Count-1; i >= 0; i--)
        {
            yield return items[i];
        }
    }
    

    This will be faster than Enumerable.Reverse() which buffers all the data first. (I don't believe Reverse has any optimisations applied in the way that Count() does.) Note that this buffering means that the data is read completely when you first start iterating, whereas FastReverse will "see" any changes made to the list while you iterate. (It will also break if you remove multiple items between iterations.)

    For general sequences, there's no way of iterating in reverse - the sequence could be infinite, for example:

    public static IEnumerable<T> GetStringsOfIncreasingSize()
    {
        string ret = "";
        while (true)
        {
            yield return ret;
            ret = ret + "x";
        }
    }
    

    What would you expect to happen if you tried to iterate over that in reverse?

    0 讨论(0)
  • 2020-11-27 04:28

    If you use a List<T>, you can also use this code:

    List<string> list = new List<string>();
    list.Add("1");
    list.Add("2");
    list.Add("3");
    list.Reverse();
    

    This is a method that write the list reverse in itself.

    Now the foreach:

    foreach(string s in list)
    {
        Console.WriteLine(s);
    }
    

    The output is:

    3
    2
    1
    
    0 讨论(0)
  • 2020-11-27 04:31

    It is possible if you can change the collection code that implements IEnumerable or IEnumerable (e.g. your own implementation of IList).

    Create an Iterator doing this job for you, for example like the following implementation through the IEnumerable interface (assuming 'items' is a List field in this sample):

    public IEnumerator<TObject> GetEnumerator()
    {
        for (var i = items.Count - 1; i >= 0; i--)
        { 
            yield return items[i];
        }
    }
    
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
    

    Because of this your List will iterate in reverse order through your list.

    Just a hint: You should clearly state this special behaviour of your list within the documentation (even better by choosing a self-explaining class name like Stack or Queue, too).

    0 讨论(0)
  • 2020-11-27 04:31

    No. ForEach just iterates through collection for each item and order depends whether it uses IEnumerable or GetEnumerator().

    0 讨论(0)
  • 2020-11-27 04:32

    I have used this code which worked

                    if (element.HasAttributes) {
    
                        foreach(var attr in element.Attributes().Reverse())
                        {
    
                            if (depth > 1)
                            {
                                elements_upper_hierarchy_text = "";
                                foreach (var ancest  in element.Ancestors().Reverse())
                                {
                                    elements_upper_hierarchy_text += ancest.Name + "_";
                                }// foreach(var ancest  in element.Ancestors())
    
                            }//if (depth > 1)
                            xml_taglist_report += " " + depth  + " " + elements_upper_hierarchy_text+ element.Name + "_" + attr.Name +"(" + attr.Name +")" + "   =   " + attr.Value + "\r\n";
                        }// foreach(var attr in element.Attributes().Reverse())
    
                    }// if (element.HasAttributes) {
    
    0 讨论(0)
  • 2020-11-27 04:36

    When working with a list (direct indexing), you cannot do it as efficiently as using a for loop.

    Edit: Which generally means, when you are able to use a for loop, it's likely the correct method for this task. Plus, for as much as foreach is implemented in-order, the construct itself is built for expressing loops that are independent of element indexes and iteration order, which is particularly important in parallel programming. It is my opinion that iteration relying on order should not use foreach for looping.

    0 讨论(0)
提交回复
热议问题