如何将linq结果转换为HashSet或HashedSet
我有一个属于ISet的类。 我试图得到一个linq查询的结果到该属性,但无法弄清楚如何做到这一点。
基本上,寻找这个的最后部分:
ISet<T> foo = new HashedSet<T>(); foo = (from x in bar.Items select x).SOMETHING;
也可以这样做:
HashSet<T> foo = new HashSet<T>(); foo = (from x in bar.Items select x).SOMETHING;
编辑:这是我最终做的:
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()); }
我不认为这里有什么内置的东西,但是写一个扩展方法真的很简单:
public static class Extensions { public static HashSet<T> ToHashSet<T>( this IEnumerable<T> source, IEqualityComparer<T> comparer = null) { return new HashSet<T>(source, comparer); } }
请注意,您确实需要扩展方法(或者至less是某种forms的generics方法),因为您可能无法明确地表示T
的types:
var query = from i in Enumerable.Range(0, 10) select new { i, j = i + 1 }; var resultSet = query.ToHashSet();
您不能通过显式调用HashSet<T>
构造函数来完成此操作。 我们依靠generics方法的types推断来为我们做。
现在你可以select命名ToSet
并返回ISet<T>
– 但是我会坚持使用ToHashSet
和具体的types。 这与标准的LINQ操作符( ToDictionary
, ToList
)是一致的,并允许将来的扩展(例如ToSortedSet
)。 您可能还想提供一个指定要使用的比较的重载。
只需将您的IEnumerable传递给HashSet的构造函数。
HashSet<T> foo = new HashSet<T>(from x in bar.Items select x);
正如@Joel所说的,你可以将你的enumerable传递进去。如果你想做一个扩展方法,你可以这样做:
public static HashSet<T> ToHashSet<T>(this IEnumerable<T> items) { return new HashSet<T>(items); }
如果你只需要只读访问权限,而源码是你的方法的一个参数,那么我会去
public static ISet<T> EnsureSet<T>(this IEnumerable<T> source) { ISet<T> result = source as ISet<T>; if (result != null) return result; return new HashSet<T>(source); }
原因是用户可能已经用ISet
调用了你的方法,所以你不需要创build副本。
这很简单:)
var foo = new HashSet<T>(from x in bar.Items select x);
是的T是由OP指定的types:)
您可以使用IEnumerable HashSet构造函数。
HashSet<T> foo = new HashSet<T>((from x in bar.Items select x).ToArray());
Jon的回答是完美的。 唯一需要注意的是,使用NHibernate的HashedSet,我需要将结果转换为集合。 有没有一个最佳的方式来做到这一点?
ISet<string> bla = new HashedSet<string>((from b in strings select b).ToArray());
要么
ISet<string> bla = new HashedSet<string>((from b in strings select b).ToList());
还是我错过了别的?
将IEnumerable简单转换为HashSet,而不是将另一个对象的属性转换为HashSet。 你可以这样写:
var set = myObject.Select(o => o.Name).ToHashSet();
但是,我的select是使用select器:
var set = myObject.ToHashSet(o => o.Name);
他们做同样的事情,而第二个显然更短,但我觉得这个习语更适合我的大脑(我认为它就像ToDictionary)。
这是使用扩展方法,支持自定义比较器作为奖励。
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); }