Is there an easy way to combine two ordered sequences using LINQ?

Considering

IEnumerable<T> first; IEnumerable<T> second; 

and that first and second ordered by comparing Func<T, T, int> , which returns 0 for equality, -1 when the first is less and 1 when the second is less.

Is there a direct way to use LINQ to combine two sequences in such a way that the resulting sequence is also ordered by the same comparator?

We are currently using a manual algorithm that works, but the convenience of reading the straightforward LINQ statement would be preferable.

+8
c # linq
source share
2 answers

You can define an extension method for this. Something like

 public static IEnumerable<T> MergeSorted<T>(this IEnumerable<T> first, IEnumerable<T> second, Func<T, T, int> comparer) { using (var firstEnumerator = first.GetEnumerator()) using (var secondEnumerator = second.GetEnumerator()) { var elementsLeftInFirst = firstEnumerator.MoveNext(); var elementsLeftInSecond = secondEnumerator.MoveNext(); while (elementsLeftInFirst || elementsLeftInSecond) { if (!elementsLeftInFirst) { do { yield return secondEnumerator.Current; } while (secondEnumerator.MoveNext()); yield break; } if (!elementsLeftInSecond) { do { yield return firstEnumerator.Current; } while (firstEnumerator.MoveNext()); yield break; } if (comparer(firstEnumerator.Current, secondEnumerator.Current) < 0) { yield return firstEnumerator.Current; elementsLeftInFirst = firstEnumerator.MoveNext(); } else { yield return secondEnumerator.Current; elementsLeftInSecond = secondEnumerator.MoveNext(); } } } } 

Using:

 var s1 = new[] { 1, 3, 5, 7, 9 }; var s2 = new[] { 2, 4, 6, 6, 6, 8 }; var merged = s1.MergeSorted(s2, (a, b) => a > b ? 1 : -1).ToList(); Console.WriteLine(string.Join(", ", merged)); 

Output:

 1, 2, 3, 4, 5, 6, 6, 6, 7, 8, 9 
+11
source share

I think converting the first one being enumerated into a list and adding the second element to this list, then calling the sort will do the trick.

  IEnumerable<int> first = new List<int>(){1,3}; IEnumerable<int> second = new List<int>(){2,4}; var temp = first.ToList(); temp.AddRange(second); temp.Sort(new Comparison<int>(comparer)); // where comparer is Func<T,T,int> 
0
source share

All Articles