Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How would you implement LINQ methods with SelectMany? [closed]

Erik Meijer is fond of pointing out that every LINQ function could actually be implemented by SelectMany; everything else is just a convenience.

This is what Eric Lippert says answering a question about monads, but I've heard Erik Meijer say this in other videos about LINQ and Rx. (Simply put, Erik Meijer is the guy who created LINQ and Rx)

I wonder how you would implement some of the most used LINQ functions with SelectMany? Ignore perfromance for now, let's focus on elegance and succinctness.

  • Where
  • Select
  • First
  • Take(n)
  • TakeWhile
  • GroupBy
  • OrderBy
  • Zip
  • Others...
like image 627
lukebuehler Avatar asked Oct 23 '13 13:10

lukebuehler


People also ask

What is the use of SelectMany in Linq?

The SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TResult>>) method enumerates the input sequence, uses a transform function to map each element to an IEnumerable<T>, and then enumerates and yields the elements of each such IEnumerable<T> object.

What is the difference between the Select clause and SelectMany () method in Linq?

Select and SelectMany are projection operators. A select operator is used to select value from a collection and SelectMany operator is used to selecting values from a collection of collection i.e. nested collection.

How do you use SelectMany?

SelectMany(<selector>) method For example, SelectMany() can turn a two-dimensional array into a single sequence of values, as shown in this example: int[][] arrays = { new[] {1, 2, 3}, new[] {4}, new[] {5, 6, 7, 8}, new[] {12, 14} }; // Will return { 1, 2, 3, 4, 5, 6, 7, 8, 12, 14 } IEnumerable<int> result = arrays.


1 Answers

The main bit to keep in mind is that SelectMany works on an IEnumerable and returns an IEnumerable using lambda expressions that have access to the current item and its index. So anything you could do to transform the result with access to the current item or its index is possible:

  • Decide which elements to keep or throw away (Where, First, Take, Skip, TakeWhile)
  • Change elements and return new ones (Select)
  • Do other stuff? (GroupBy, honestly don't know how I would implement that without some thought)

This simple Where example will make it clear how many of these could be accomplished easily:

SomeList.SelectMany(x =>
    ShouldBeIncluded(x) ?
        Enumerable.Repeat(x, 1) :
        Enumerable.Empty<AClass>();
    );

Edit - Great link posted by Tim Schmelter in the comments proves again that Jon Skeet has already done it cleaner:

return Enumerable.Repeat(x, ShouldBeIncluded(x) ? 1 : 0;
like image 134
Ocelot20 Avatar answered Sep 30 '22 18:09

Ocelot20