我有一个类型的对象集合,我想将其转换为其他类型。这可以通过foreach轻松完成,但我想弄清楚如何使用Linq的聚合函数来完成它。
问题是所有Aggregate示例都使用类型line 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)) );
问题是List&lt;&gt; .Add返回void。 Aggregate的第二个参数的返回类型需要是List。
如果我有一个支持'+'类型语义的列表类型,我可以创建第二个参数
list + item
但是我找不到任何支持此类事物的集合类型。
在Linq中,这似乎很容易实现。有办法吗?此外,如果我错过了一个更简单的方法,我也很想了解这一点。谢谢!
答案 0 :(得分: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;
});
答案 1 :(得分:10)
我认为拨打Select和ToList()的电话可能就是您需要的。例如:
context.Items
.Select(item => new DestinationType(item.A, item.B, item.C))
.ToList();
答案 2 :(得分:4)
您可以在这里申请select
。
var newSet = set.Select(item => new DestinationType(...)).ToList();
Aggregate
(通常称为fold
或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]
如果您真的想使用aggregate
进行此计算,请使用Dustin的解决方案或更好地为不可变集合实现基于链接列表的类型(您甚至可以为此类型提供operator +
)。 / p>
答案 3 :(得分:3)
list.AddRange(context.Items.Select(item =>
new DestinationType(item.A, item.B, item.C));
我意识到它不使用Aggregate函数,但您应该找到一个更好的示例来用于学习聚合。
答案 4 :(得分: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);