如何使用Linq的聚合函数C#添加到列表

Sla*_*ggg 9 c# linq aggregate

我有一个类型的对象集合,我想转换为不同的类型.这可以通过foreach轻松完成,但我想弄清楚如何使用Linq的聚合函数来完成它.

问题是所有Aggregate示例都使用类型行string或int,它们支持'+'运算符.我希望累加器类型是一个列表,它不支持'+'语义.

这是一个简单的例子:

public class DestinationType
{
    public DestinationType(int A, int B, int C) { ... }
}

var set = from item in context.Items
          select new { item.A, item.B, item.C };

var newSet = set.Aggregate( new List<DestinationType>(),
                            (list, item) => list.Add(new DestinationType(item.A, item.B, item.C)) );
Run Code Online (Sandbox Code Playgroud)

问题是List <>.添加返回void.Aggregate的第二个参数的返回类型需要是List.

如果我有一个支持'+'类型语义的列表类型,我可以创建第二个参数

list + item
Run Code Online (Sandbox Code Playgroud)

但是我找不到任何支持这种东西的集合类型.

在Linq中,这似乎很容易实现.有办法吗?此外,如果我错过了一个更简单的方法,我也很想了解这一点.谢谢!

Dus*_*ell 25

假设这是LINQ to Objects,试试......

var newSet = set.Aggregate(new List<DestinationType>(),
                                    (list, item) =>
                                    {
                                        list.Add(new DestinationType(item.A, item.B, item.C));
                                        return list;
                                    });
Run Code Online (Sandbox Code Playgroud)


Sam*_*ack 10

我认为调用SelectToList()结合可能就是你需要的.例如:

context.Items
  .Select(item => new DestinationType(item.A, item.B, item.C))
  .ToList();
Run Code Online (Sandbox Code Playgroud)


Dar*_*rio 5

您只需select在这里申请即可。

var newSet = set.Select(item => new DestinationType(...)).ToList();
Run Code Online (Sandbox Code Playgroud)

Aggregate(通常称为foldor reduce)用于将元素组合select在一起,其中将函数应用于每个元素。

前任:

f为一元函数,则 等于。[a, b, c].select(f)[f(a), f(b), f(c)]

f为二元函数,则等于。[a, b, c].aggregate(f, init)f(a, f(b, f(c, init)))

您在示例中选择的方式在 C# 中并不常见,但在函数式编程中经常使用,其中(链接)列表被转换为新列表,而不是更改现有集合:

reversed = fold (\list element -> element:list) [] [1..10]
Run Code Online (Sandbox Code Playgroud)

如果您确实想使用 进行此计算aggregate,请使用达斯汀的解决方案或更好地为不可变集合实现基于链接列表的类型(您甚至可以为该类型指定operator +)。