andleer
andleer

Reputation: 22568

LINQ OrderBy with IEnumerable<T> key

I have an IEnumerable that I want to sort not within each sequence but from sequence to sequence.

new [] {"Z", "B", "C" }
new [] {"A", "B", "C" }
new [] {"B", "B", "C" }

becomes

new [] {"A", "B", "C" }
new [] {"B", "B", "C" }
new [] {"Z", "B", "C" }

Is there an existing approach with LINQ or do I need to roll my own IComparer?

Upvotes: 2

Views: 285

Answers (1)

Eric Lippert
Eric Lippert

Reputation: 660024

There's nothing built in. It's straightforward to roll your own helper method; it's one line provided that the sequences are the same length.

static int SequenceCompare<T>(
    this IEnumerable<T> x, 
    IEnumerable<T> y, 
    Func<T, T, int> comparer) =>
  x.Zip(y, comparer).FirstOrDefault(c => c != 0);

Now if you can compare two members of a sequence, you can also compare two sequences.

This doesn't work if the sequences are of unequal length; you have to do a bit more work to say that "A", "B", "C" is "bigger" than "A", "B".

Exercise: Solve the problem for sequences of unequal length. (Hint: Examine the implementation of Zip and modify it accordingly.)

Exercise: Suppose we have a comparison function Func<T, T, int>. We've seen how to extend it to Func<IEnumerable<T>, IEnumerable<T>, int>. Now suppose the arguments were Task<T>, or Func<T> or Nullable<T> or Lazy<T> -- how might you similarly implement a comparison? Which of those are easy and which of them are hard, and why?

Upvotes: 5

Related Questions