By Joe


2009-09-23 15:20:35 8 Comments

Just a little niggle about LINQ syntax. I'm flattening an IEnumerable<IEnumerable<T>> with SelectMany(x => x).

My problem is with the lambda expression x => x. It looks a bit ugly. Is there some static 'identity function' object that I can use instead of x => x? Something like SelectMany(IdentityFunction)?

7 comments

@jbtule 2015-08-21 13:43:25

With C# 6.0 and if you reference FSharp.Core you can do:

using static Microsoft.FSharp.Core.Operators

And then you're free to do:

SelectMany(Identity)

@bug 2018-09-13 15:18:14

FSharp.Core is a big dependency to ask. probably not worth it unless you're actually writing F#

@Jon Skeet 2009-09-23 15:23:43

Note: this answer was correct for C# 3, but at some point (C# 4? C# 5?) type inference improved so that the IdentityFunction method shown below can be used easily.


No, there isn't. It would have to be generic, to start with:

public static Func<T, T> IdentityFunction<T>()
{
    return x => x;
}

But then type inference wouldn't work, so you'd have to do:

SelectMany(Helpers.IdentityFunction<Foo>())

which is a lot uglier than x => x.

Another possibility is that you wrap this in an extension method:

public static IEnumerable<T> Flatten<T>
    (this IEnumerable<IEnumerable<T>> source)
{
    return source.SelectMany(x => x);
}

Unfortunately with generic variance the way it is, that may well fall foul of various cases in C# 3... it wouldn't be applicable to List<List<string>> for example. You could make it more generic:

public static IEnumerable<TElement> Flatten<TElement, TWrapper>
    (this IEnumerable<TWrapper> source) where TWrapper : IEnumerable<TElement>
{
    return source.SelectMany(x => x);
}

But again, you've then got type inference problems, I suspect...

EDIT: To respond to the comments... yes, C# 4 makes this easier. Or rather, it makes the first Flatten method more useful than it is in C# 3. Here's an example which works in C# 4, but doesn't work in C# 3 because the compiler can't convert from List<List<string>> to IEnumerable<IEnumerable<string>>:

using System;
using System.Collections.Generic;
using System.Linq;

public static class Extensions
{
    public static IEnumerable<T> Flatten<T>
        (this IEnumerable<IEnumerable<T>> source)
    {
        return source.SelectMany(x => x);
    }
}

class Test
{
    static void Main()
    {
        List<List<string>> strings = new List<List<string>>
        {
            new List<string> { "x", "y", "z" },
            new List<string> { "0", "1", "2" }
        };

        foreach (string x in strings.Flatten())
        {
            Console.WriteLine(x);
        }
    }
}

@Joe 2009-09-23 15:29:49

Thanks! That's given me some interesting leads too. I think I'll stay with x => x for the time being...

@Meta-Knight 2009-09-23 18:00:57

I tried to create a Flatten extension method too (which I called SelectMany but the goal was the same) and because of the problem with variance it wasn't really useful, I would need many overloads, so I went back to x => x... Jon, would a Flatten extension method be easier to do in C#4 / VB10?

@Jon Skeet 2009-09-23 18:29:41

@MetaKnight: Will edit post...

@Dave Cousineau 2012-06-05 08:00:40

why did you write a function that returns a function? shouldn't all you need be a single function with a Func<T, T> signature that does nothing but return its input?

@Jon Skeet 2012-06-05 08:03:19

@Sahuagin: I didn't write a function that returns a function. I wrote a function that returns an IEnumerable<T>. It's not clear what you're suggesting, but maybe you should add it as an answer if you think it would be simpler than my suggestion.

@Dave Cousineau 2012-06-05 08:06:36

@JonSkeet I mean for the identity function. You wrote public static Func<T, T> IdentityFunction<T>() which isn't an identity function, it's a function that returns an identity function. Was that necessary in C# 3? I have added my version as an answer.

@Willem Van Onsem 2014-07-29 00:43:10

Shouldn't it be more efficient, to code the identity function: static T Id<T> (T t) {return t;}. Will the presented method not allocate a new function each time one calls the IdentityFunction method?

@Jon Skeet 2014-07-29 05:45:08

@CommuSoft: No - in fact, if you wrote your Id method and called SelectMany(Id), that would create a new delegate on each call (due to a bit of language spec stupidity) but the code I've given will reuse the delegate every time, due to compiler optimizations.

@FrankB 2016-08-02 07:19:54

@JonSkeet I realise this is VERY old - but is it possible that in VS2012 and newer this problem is solved - and we can directly use a static Id function (instead of your suggested generator function)? A quick performace comparion sugessted this...

@Jon Skeet 2016-08-02 07:37:38

@FrankB: Hmm. Not sure when that was improved, but yes, it seems okay with C# 6, anyway. Can't edit right now, but will do when I get a chance.

@Ostati 2015-12-01 19:15:24

I'd go with a simple class with a single static property and add as many as required down the line

    internal class IdentityFunction<TSource>
    {
        public static Func<TSource, TSource> Instance
        {
            get { return x => x; }
        }
    }

    SelectMany(IdentityFunction<Foo>.Instance)

@ie. 2015-01-20 09:27:43

With C# 6.0 things are getting better. We can define the Identity function in the way suggested by @Sahuagin:

static class Functions
{
    public static T It<T>(T item) => item;
}

and then use it in SelectMany the using static constructor:

using Functions;

...

var result = enumerableOfEnumerables.SelectMany(It);

I think it looks very laconic in the such way. I also find Identity function useful when building dictionaries:

class P
{
    P(int id, string name) // sad, we are not getting Primary Constructors in C# 6.0
    {
        ID = id;
        Name = id;
    }

    int ID { get; }
    int Name { get; }

    static void Main(string[] args)
    {
        var items = new[] { new P(1, "Jack"), new P(2, "Jill"), new P(3, "Peter") };
        var dict = items.ToDictionary(x => x.ID, It);
    }
}

@Dave Cousineau 2012-06-05 08:00:51

Unless I misunderstand the question, the following seems to work fine for me in C# 4:

public static class Defines
{
   public static T Identity<T>(T pValue)
   {
      return pValue;
   }

   ...

You can then do the following in your example:

var result =
   enumerableOfEnumerables
   .SelectMany(Defines.Identity);

As well as use Defines.Identity anywhere you would use a lambda that looks like x => x.

@Anthony 2012-11-05 20:59:26

I know this was a late submission, but I really feel like it answers the question better.

@Bryan Watts 2009-09-23 23:31:12

Does this work in the way you want? I realize Jon posted a version of this solution, but he has a second type parameter which is only necessary if the resulting sequence type is different from the source sequence type.

public static IEnumerable<T> Flatten<T>(this IEnumerable<T> source)
    where T : IEnumerable<T>
{
    return source.SelectMany(item => item);
}

@Kobi 2009-09-23 17:00:49

You can get close to what you need. Instead of a regular static function, consider an Extension Method for your IEnumerable<T>, as if the identity function is of the collection, not the type (a collection can generate the identity function of its items):

public static Func<T, T> IdentityFunction<T>(this IEnumerable<T> enumerable)
{
     return x => x;
}

with this, you don't have to specify the type again, and write:

IEnumerable<IEnumerable<T>> deepList = ... ;
var flat = deepList.SelectMany(deepList.IdentityFunction());

This does feel a bit abusive though, and I'd probably go with x=>x. Also, you cannot use it fluently (in chaining), so it will not always be useful.

@Bryan Watts 2009-09-23 23:23:32

You need to return Func<T, IEnumerable<T>> to make it work with SelectMany.

@Kobi 2009-09-24 06:25:37

True, it works for Select but fails for SelectMany - it cant figure out the types. shame.

Related Questions

Sponsored Content

7 Answered Questions

[SOLVED] Multiple "order by" in LINQ

  • 2008-11-18 13:34:11
  • Sasha
  • 566564 View
  • 1519 Score
  • 7 Answer
  • Tags:   linq sql-order-by

10 Answered Questions

[SOLVED] IEnumerable vs List - What to Use? How do they work?

9 Answered Questions

[SOLVED] Group by in LINQ

  • 2011-09-06 19:44:20
  • test123
  • 1182378 View
  • 983 Score
  • 9 Answer
  • Tags:   c# linq group-by

21 Answered Questions

296 Answered Questions

[SOLVED] Hidden Features of C#?

  • 2008-08-12 16:32:24
  • Serhat Ozgel
  • 673449 View
  • 1475 Score
  • 296 Answer
  • Tags:   c# hidden-features

19 Answered Questions

[SOLVED] Dynamic LINQ OrderBy on IEnumerable<T> / IQueryable<T>

18 Answered Questions

[SOLVED] Distinct() with lambda?

5 Answered Questions

[SOLVED] Is there a reason for C#'s reuse of the variable in a foreach?

4 Answered Questions

[SOLVED] Linq - SelectMany Confusion

1 Answered Questions

[SOLVED] Multiple Order By with LINQ

  • 2010-02-23 14:35:13
  • sdanna
  • 158362 View
  • 211 Score
  • 1 Answer
  • Tags:   c# linq lambda

Sponsored Content