HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpCritical

Preserving order with LINQ

Submitted by: @import:stackoverflow-api··
0
Viewed 0 times
withlinqpreservingorder

Problem

I use LINQ to Objects instructions on an ordered array.
Which operations shouldn't I do to be sure the order of the array is not changed?

Solution

I examined the methods of System.Linq.Enumerable, discarding any that returned non-IEnumerable results. I checked the remarks of each to determine how the order of the result would differ from order of the source.

Preserves Order Absolutely. You can map a source element by index to a result element

  • AsEnumerable



  • Cast



  • Concat



  • Select



  • ToArray



  • ToList



Preserves Order. Elements are filtered or added, but not re-ordered.

  • Distinct



  • Except



  • Intersect



  • OfType



  • Prepend (new in .net 4.7.1)



  • Skip



  • SkipWhile



  • Take



  • TakeWhile



  • Where



  • Zip (new in .net 4)



Destroys Order - we don't know what order to expect results in.

  • ToDictionary



  • ToLookup



Redefines Order Explicitly - use these to change the order of the result

  • OrderBy



  • OrderByDescending



  • Reverse



  • ThenBy



  • ThenByDescending



Redefines Order according to some rules.

  • GroupBy - The IGrouping objects are yielded in an order based on the order of the elements in source that produced the first key of each IGrouping. Elements in a grouping are yielded in the order they appear in source.



  • GroupJoin - GroupJoin preserves the order of the elements of outer, and for each element of outer, the order of the matching elements from inner.



  • Join - preserves the order of the elements of outer, and for each of these elements, the order of the matching elements of inner.



  • SelectMany - for each element of source, selector is invoked and a sequence of values is returned.



  • Union - When the object returned by this method is enumerated, Union enumerates first and second in that order and yields each element that has not already been yielded.



Edit: I've moved Distinct to Preserving order based on this implementation.

private static IEnumerable DistinctIterator
      (IEnumerable source, IEqualityComparer comparer)
    {
        Set set = new Set(comparer);
        foreach (TSource element in source)
            if (set.Add(element)) yield return element;
    }

Code Snippets

private static IEnumerable<TSource> DistinctIterator<TSource>
      (IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
    {
        Set<TSource> set = new Set<TSource>(comparer);
        foreach (TSource element in source)
            if (set.Add(element)) yield return element;
    }

Context

Stack Overflow Q#204505, score: 770

Revisions (0)

No revisions yet.