Don*_*nut 80 c# linq generics collections
假设我有任意数量的集合,每个集合包含相同类型的对象(例如,List<int> foo和List<int> bar).如果这些集合本身就是一个集合(例如,类型List<List<int>>,我可以使用SelectMany它们将它们全部合并到一个集合中.
但是,如果这些集合不在同一个集合中,那么我的印象是我必须编写这样的方法:
public static IEnumerable<T> Combine<T>(params ICollection<T>[] toCombine)
{
return toCombine.SelectMany(x => x);
}
Run Code Online (Sandbox Code Playgroud)
然后我会这样称呼:
var combined = Combine(foo, bar);
Run Code Online (Sandbox Code Playgroud)
是否有一种干净,优雅的方式来组合(任意数量)集合而无需编写Combine如上所述的实用方法?看起来很简单,应该有一种方法在LINQ中做到,但也许不是.
Dom*_*nic 88
我想你可能在寻找LINQ的.Concat()?
var combined = foo.Concat(bar).Concat(foobar).Concat(...);
Run Code Online (Sandbox Code Playgroud)
或者,.Union()将删除重复的元素.
naw*_*fal 24
对我来说,Concat作为一种扩展方法在我的代码中并不是很优雅,因为我有多个大序列要连接.这只是一个codde缩进/格式化问题,而且非常个人化.
当然看起来像这样:
var list = list1.Concat(list2).Concat(list3);
Run Code Online (Sandbox Code Playgroud)
读起来不太可读:
var list = list1.Select(x = > x)
.Concat(list2.Where(x => true)
.Concat(list3.OrderBy(x => x));
Run Code Online (Sandbox Code Playgroud)
或者当它看起来像:
return Normalize(list1, a, b)
.Concat(Normalize(list2, b, c))
.Concat(Normalize(list3, c, d));
Run Code Online (Sandbox Code Playgroud)
或者你喜欢的格式是什么.随着更复杂的concats,事情变得更糟.我对上述风格的认知失调的原因是第一个序列位于Concat方法之外,而后续序列位于内部.我更喜欢Concat直接调用静态方法而不是扩展样式:
var list = Enumerable.Concat(list1.Select(x => x),
list2.Where(x => true));
Run Code Online (Sandbox Code Playgroud)
对于更多序列的concats,我使用与OP中相同的静态方法:
public static IEnumerable<T> Concat<T>(params IEnumerable<T>[] sequences)
{
return sequences.SelectMany(x => x);
}
Run Code Online (Sandbox Code Playgroud)
所以我可以写:
return EnumerableEx.Concat
(
list1.Select(x = > x),
list2.Where(x => true),
list3.OrderBy(x => x)
);
Run Code Online (Sandbox Code Playgroud)
看起来更好.考虑到我的序列看起来更干净,我必须写的额外的,否则多余的类名对我来说不是问题Concat.这不是C#6中的问题.你可以写:
return Concat(list1.Select(x = > x),
list2.Where(x => true),
list3.OrderBy(x => x));
Run Code Online (Sandbox Code Playgroud)
希望我们在C#中有列表连接运算符,类似于:
list1 @ list2 // F#
list1 ++ list2 // Scala
Run Code Online (Sandbox Code Playgroud)
那种方式更清洁.
ast*_*sov 22
List<List<T>> 这是正确的"优雅"方式:
var combined = lists.Aggregate((acc, list) => { return acc.Concat(list); });
Run Code Online (Sandbox Code Playgroud)
jas*_*son 14
使用Enumerable.Concat如下:
var combined = foo.Concat(bar).Concat(baz)....;
Run Code Online (Sandbox Code Playgroud)
小智 7
你总是可以使用Aggregate和Concat结合...
var listOfLists = new List<List<int>>
{
new List<int> {1, 2, 3, 4},
new List<int> {5, 6, 7, 8},
new List<int> {9, 10}
};
IEnumerable<int> combined = new List<int>();
combined = listOfLists.Aggregate(combined, (current, list) => current.Concat(list)).ToList();
Run Code Online (Sandbox Code Playgroud)
我看到的唯一方法是使用 Concat()
var foo = new List<int> { 1, 2, 3 };
var bar = new List<int> { 4, 5, 6 };
var tor = new List<int> { 7, 8, 9 };
var result = foo.Concat(bar).Concat(tor);
Run Code Online (Sandbox Code Playgroud)
但你应该决定什么是更好的:
var result = Combine(foo, bar, tor);
Run Code Online (Sandbox Code Playgroud)
要么
var result = foo.Concat(bar).Concat(tor);
Run Code Online (Sandbox Code Playgroud)
有一点,为什么Concat()会是更好的选择是,这将是另一个开发者更为明显.更具可读性和简单性.