优雅的方式来结合多个元素的集合?
说我有任意数量的集合,每个集合包含相同types的对象(例如, 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); } 
然后我会这样叫:
 var combined = Combine(foo, bar); 
 有没有一个干净,优雅的方式来结合(任意数量)的集合,而无需编写像上面的Combine这样的实用程序方法? 看起来很简单,在LINQ中应该有办法做到,但也许不行。 
 我想你可能正在寻找LINQ的.Concat() ? 
 var combined = foo.Concat(bar).Concat(foobar).Concat(...); 
 或者, .Union()将删除重复的元素。 
 使用Enumerable.Concat像这样: 
 var combined = foo.Concat(bar).Concat(baz)....; 
 对我来说Concat作为扩展方法在我的代码中不是很优雅,当我有多个大序列来连接。 这只是一个缩进/格式化问题,还有一些非常个人化的问题。 
当然,看起来像这样:
 var list = list1.Concat(list2).Concat(list3); 
当它读取时不太可读:
 var list = list1.Select(x = > x) .Concat(list2.Where(x => true) .Concat(list3.OrderBy(x => x)); 
或者当它看起来像:
 return Normalize(list1, a, b) .Concat(Normalize(list2, b, c)) .Concat(Normalize(list3, c, d)); 
 或者你喜欢的格式是什么。 事情变得更加复杂连接。 我认为与上述风格不一致的原因是第一个序列位于Concat方法之外,而后面的序列位于内部。 我宁愿直接调用静态的Concat方法,而不是扩展风格: 
 var list = Enumerable.Concat(list1.Select(x => x), list2.Where(x => true)); 
对于更多数量的连续序列,我使用与OP中相同的静态方法:
 public static IEnumerable<T> Concat<T>(params IEnumerable<T>[] sequences) { return sequences.SelectMany(x => x); } 
所以我可以写:
 return EnumerableEx.Concat ( list1.Select(x = > x), list2.Where(x => true), list3.OrderBy(x => x) ); 
 看起来更好。 额外,否则冗余,我必须写的类名是不是我的问题,考虑到我的序列看起来更干净的Concat调用。 这在C#6中不是什么问题。 你可以写: 
 return Concat(list1.Select(x = > x), list2.Where(x => true), list3.OrderBy(x => x)); 
 使用Enumerable.Concact : 
 var query = foo.Concat(bar); 
 我看到的唯一方法是使用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); 
但是你应该决定什么是更好的:
 var result = Combine(foo, bar, tor); 
要么
 var result = foo.Concat(bar).Concat(tor); 
  Concat()将是一个更好的select的一点是,对于另一个开发者来说,它会更加明显。 更可读和简单。 
  Enumerable.Aggregate是正确的“优雅”的方式来做到这一点: 
 var all = lists.Aggregate((acc, list) => { return acc.Concat(list); }); 
你可以使用Union如下:
 var combined=foo.Union(bar).Union(baz)... 
 这将删除相同的元素,所以如果你有这些元素,你可能想用Concat来代替。 
鉴于你从一堆单独的集合开始,我认为你的解决scheme是相当优雅的。 你将不得不做一些缝合在一起的东西 。
使用Combine方法可以在语法上更方便地使用扩展方法,这将使您可以在任何地方使用它。
你总是可以使用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(); 
 所有你需要的是,对于任何IEnumerable<IEnumerable<T>> lists : 
 var combined = lists.Aggregate((l1, l2) => l1.Concat(l2)); 
 这将把lists所有项目合并为一个IEnumerable<T> (带有重复项)。 如其他答案中所述,使用Union而不是Concat删除重复项。