我有一个List(Of HashSet(Of String))
.是否有一种清晰的单行 LINQ 方法来获取包含列表条目值中所有字符串的单个HashSet(Of String)
?
例如,从 3 个哈希集 {"A"}、{"A","B","C"} 和 {"B","C","D"} 中,我想要一个哈希集 {"A","B","C","D"}。
我很确定我可以用.Aggregate()
或.Accumulate()
做点什么.
C# 或 VB.NET 解释同样有用。
只使用SelectMany
.在 C# 中:
var newHashSet = new HashSet<string>(myListOfHashSets.SelectMany(x => x));
在 VB.NET:
Dim newHashSet As New HashSet(Of String)(myListOfHashSets.SelectMany(Function (x) x))
SelectMany
正是这样做的。在高级别(省略泛型并简化一点),SelectMany
实现如下:
static IEnumerable SelectMany(this source, Func selector)
{
IEnumerable results;
foreach (var item in source)
{
foreach (var result in selector(item))
{
results.add(result);
}
}
return results;
}
上面的代码实际上并不准确;相反,它使用收益返回来懒惰地执行选择,并且不使用中间收集results
。最后,完整的签名实际上是public static IEnumerable<TResult> SelectMany<TSource, TResult>(
this IEnumerable<TSource> source,
Func<TSource, IEnumerable<TResult>> selector)
的,但唯一需要理解的重要部分是选择器返回一个集合。如果你有一个集合集合,那么使用标识函数x => x
就可以做到这一点。
因此,它将集合的集合平展为单个集合。使用标识函数x => x
作为选择器意味着内部集合的元素保持不变。因此,正如其他一些人所发布的那样,最终答案是:
var newSet = new HashSet(setOfSets.SelectMany(element => element));
您可以尝试使用HashSet的UnionWith方法。它将是这样的:
var result = myListOfHashSets.Aggregate(new HashSet<string>(), (x, y) => { x.UnionWith(y); return x; });