How to convert linq results to HashSet or HashedSet

前端 未结 9 709
闹比i
闹比i 2020-11-28 05:17

I have a property on a class that is an ISet. I\'m trying to get the results of a linq query into that property, but can\'t figure out how to do so.

Basically, look

相关标签:
9条回答
  • 2020-11-28 05:42

    There is an extension method build in the .NET framework and in .NET core for converting an IEnumerable to a HashSet: https://docs.microsoft.com/en-us/dotnet/api/?term=ToHashSet

    public static System.Collections.Generic.HashSet<TSource> ToHashSet<TSource> (this System.Collections.Generic.IEnumerable<TSource> source);
    

    It appears that I cannot use it in .NET standard libraries yet (at the time of writing). So then I use this extension method:

        [Obsolete("In the .NET framework and in NET core this method is available, " +
                  "however can't use it in .NET standard yet. When it's added, please remove this method")]
    public static HashSet<T> ToHashSet<T>(this IEnumerable<T> source, IEqualityComparer<T> comparer = null) => new HashSet<T>(source, comparer);
    
    0 讨论(0)
  • 2020-11-28 05:46

    That's pretty simple :)

    var foo = new HashSet<T>(from x in bar.Items select x);
    

    and yes T is the type specified by OP :)

    0 讨论(0)
  • 2020-11-28 05:47

    As @Joel stated, you can just pass your enumerable in. If you want to do an extension method, you can do:

    public static HashSet<T> ToHashSet<T>(this IEnumerable<T> items)
    {
        return new HashSet<T>(items);
    }
    
    0 讨论(0)
  • 2020-11-28 05:48

    Jon's answer is perfect. The only caveat is that, using NHibernate's HashedSet, I need to convert the results to a collection. Is there an optimal way to do this?

    ISet<string> bla = new HashedSet<string>((from b in strings select b).ToArray()); 
    

    or

    ISet<string> bla = new HashedSet<string>((from b in strings select b).ToList()); 
    

    Or am I missing something else?


    Edit: This is what I ended up doing:

    public static HashSet<T> ToHashSet<T>(this IEnumerable<T> source)
    {
        return new HashSet<T>(source);
    }
    
    public static HashedSet<T> ToHashedSet<T>(this IEnumerable<T> source)
    {
        return new HashedSet<T>(source.ToHashSet());
    }
    
    0 讨论(0)
  • 2020-11-28 05:55

    Rather than the simple conversion of IEnumerable to a HashSet, it is often convenient to convert a property of another object into a HashSet. You could write this as:

    var set = myObject.Select(o => o.Name).ToHashSet();
    

    but, my preference would be to use selectors:

    var set = myObject.ToHashSet(o => o.Name);
    

    They do the same thing, and the the second is obviously shorter, but I find the idiom fits my brains better (I think of it as being like ToDictionary).

    Here's the extension method to use, with support for custom comparers as a bonus.

    public static HashSet<TKey> ToHashSet<TSource, TKey>(
        this IEnumerable<TSource> source,
        Func<TSource, TKey> selector,
        IEqualityComparer<TKey> comparer = null)
    {
        return new HashSet<TKey>(source.Select(selector), comparer);
    }
    
    0 讨论(0)
  • 2020-11-28 05:58

    This functionality has been added as an extension method on IEnumerable<TSource> to .NET Framework 4.7.2:

    • ToHashSet<TSource>(IEnumerable<TSource>)
    • ToHashSet<TSource>(IEnumerable<TSource>, IEqualityComparer<TSource>)
    0 讨论(0)
提交回复
热议问题