在C#.NET中将两个(或更多)列表合并为一个

时间:2010-12-20 08:43:00

标签: c# .net list

是否可以使用C#将两个或多个列表转换为单个列表?

例如,

public static List<Product> GetAllProducts(int categoryId){ .... }
.
.
.
var productCollection1 = GetAllProducts(CategoryId1);
var productCollection2 = GetAllProducts(CategoryId2);
var productCollection3 = GetAllProducts(CategoryId3);

13 个答案:

答案 0 :(得分:375)

您可以使用LINQ ConcatToList方法:

var allProducts = productCollection1.Concat(productCollection2)
                                    .Concat(productCollection3)
                                    .ToList();

请注意,有更有效的方法可以做到这一点 - 上面将基本上遍历所有条目,创建一个动态大小的缓冲区。由于您可以预测开始的大小,因此您不需要此动态大小调整...因此您可以使用:

var allProducts = new List<Product>(productCollection1.Count +
                                    productCollection2.Count +
                                    productCollection3.Count);
allProducts.AddRange(productCollection1);
allProducts.AddRange(productCollection2);
allProducts.AddRange(productCollection3);

AddRange特别为ICollection<T>提供效率。)

除非你真的需要,否则我不会采用这种方法。

答案 1 :(得分:38)

假设您想要一个包含所有指定类别ID的产品的列表,您可以将查询视为投影,然后是展平< / em>操作。有一个LINQ运算符可以做到:SelectMany

// implicitly List<Product>
var products = new[] { CategoryId1, CategoryId2, CategoryId3 }
                     .SelectMany(id => GetAllProducts(id))
                     .ToList();

在C#4中,您可以将SelectMany缩短为:.SelectMany(GetAllProducts)

如果您已经有代表每个Id的产品的列表,那么您需要的是连接,正如其他人指出的那样。

答案 2 :(得分:21)

你可以使用LINQ组合它们:

  list = list1.Concat(list2).Concat(list3).ToList();

使用List.AddRange()的传统方法可能更有效率。

答案 3 :(得分:7)

您可以使用Concat扩展方法:

var result = productCollection1
    .Concat(productCollection2)
    .Concat(productCollection3)
    .ToList();

答案 4 :(得分:7)

list4 = list1.Concat(list2).Concat(list3).ToList();

答案 5 :(得分:7)

查看List.AddRange合并列表

答案 6 :(得分:2)

我已经对它进行了评论,但我仍然认为这是一个有效的选项,只需测试您的环境是否更好的解决方案或其他解决方案。在我的特定情况下,使用source.ForEach(p => dest.Add(p))的效果优于经典AddRange,但我没有在低级别调查原因。

您可以在此处查看示例代码:https://gist.github.com/mcliment/4690433

所以选项是:

var allProducts = new List<Product>(productCollection1.Count +
                                    productCollection2.Count +
                                    productCollection3.Count);

productCollection1.ForEach(p => allProducts.Add(p));
productCollection2.ForEach(p => allProducts.Add(p));
productCollection3.ForEach(p => allProducts.Add(p));

测试它是否适合你。

免责声明:我不是在倡导这个解决方案,我发现Concat是最明确的解决方案。我刚刚在与Jon讨论时说过,在我的机器中,这个案例比AddRange表现得更好,但他说,知识远比我更多,这没有意义。如果你想比较,那就是要点。

答案 7 :(得分:1)

// I would make it a little bit more simple

 var products = new List<List<product>> {item1, item2, item3 }.SelectMany(id => id).ToList();

这样它就是一个多维List,而.SelectMany()会将它展平为IEnumerable产品,然后我会使用.ToList()方法。

答案 8 :(得分:1)

我知道这是一个老问题,我想我可能会加2美分。

如果您有List<Something>[],则可以使用Aggregate

加入他们
public List<TType> Concat<TType>(params List<TType>[] lists)
{
    var result = lists.Aggregate(new List<TType>(), (x, y) => x.Concat(y).ToList());

    return result;
}

希望这有帮助。

答案 9 :(得分:1)

将列表合并或合并到一个列表中。

  • 必须做一件事:两个列表的类型均为 相等。

  • 例如:如果我们有import { HttpClient, HttpHeaders } from '@angular/common/http'; downloadFile(file){ return this.httpClient.post('http://127.0.0.1/downloadFile',file,{ responseType : 'blob', headers : new HttpHeaders().append('content-type','application/json') }); } 的列表,则可以添加另一个列表到 现有列表具有字符串类型的列表,否则我们就不能。

示例

app.post('/downloadFile',function(req,res,next){
  filepath = path.join(__dirname,'./public/'+req.body.urloffolder+'/'+req.body.filename);
  res.sendFile(filepath);
});

答案 10 :(得分:0)

您需要使用Concat操作

答案 11 :(得分:0)

在特殊情况下:“List1的所有元素都转到新的List2”:(例如字符串列表)

List<string> list2 = new List<string>(list1);

在这种情况下,使用list1中的所有元素生成 list2

答案 12 :(得分:0)

当你列出的名单很少但你不知道究竟有多少时,请使用:

listsOfProducts包含几个填充了对象的列表。

List<Product> productListMerged = new List<Product>();

listsOfProducts.ForEach(q => q.ForEach(e => productListMerged.Add(e)));