LINQ identity function?

后端 未结 7 2118
日久生厌
日久生厌 2020-12-03 16:22

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

My problem i

相关标签:
7条回答
  • 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)
    
    0 讨论(0)
  • 2020-12-03 17: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);
    }
    
    0 讨论(0)
  • 2020-12-03 17:14

    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.

    0 讨论(0)
  • 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.

    0 讨论(0)
  • 2020-12-03 17:20

    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)
    
    0 讨论(0)
  • 2020-12-03 17:23

    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);
        }
    }
    
    0 讨论(0)
提交回复
热议问题