如何使用Linq的Aggregate函数在C#中向列表添加元素

9

我有一组同一类型的对象,我想将其转换为另一种类型。这可以使用foreach轻松完成,但我想弄清楚如何使用Linq的聚合函数来完成它。

问题在于所有的Aggregate示例都使用像字符串或整数这样支持'+'运算符的类型。我想让累加器类型成为一个列表,但列表不支持'+'语义。

以下是一个快速示例:

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)) );

问题在于List<>.Add返回的是void类型。Aggregate的第二个参数的返回类型需要是一个List。
如果我有一个支持“+”类型语义的列表类型,我可以将其作为第二个参数。
list + item

然而,我找不到任何支持这种操作的集合类型。

在 Linq 中,这应该很容易实现。有没有方法?另外,如果我错过了更简单的方法,我也很想学习。谢谢!


感谢您所有的出色答案!Sam和Talljoe使用Linq最简单地实现了这一点。再次感谢! - Slaggg
5个回答

30

假设这是针对对象的LINQ,尝试...

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

11

我认为调用Select方法并与ToList()方法结合起来,可能是你在这里需要的。例如:

context.Items
  .Select(item => new DestinationType(item.A, item.B, item.C))
  .ToList();

5
您可以在这里应用select
var newSet = set.Select(item => new DestinationType(...)).ToList();
Aggregate(通常称为foldreduce)用于将元素组合在一起,而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]

如果您真的想要使用aggregate进行此计算,请使用Dustin的解决方案或更好地实现基于链表的不可变集合类型(您甚至可以为此类型添加operator +)。

3
list.AddRange(context.Items.Select(item => 
  new DestinationType(item.A, item.B, item.C));

我知道这个例子没有使用聚合函数,但是您可能需要找到一个更好的例子来学习聚合。


1

除非我漏掉了什么显而易见的东西,否则为什么不直接这样做:

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

var newSet = from item in context.Items
    select new DestinationType(item.A, item.B, item.C);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接