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

发布于 2024-07-24 05:01:58 字数 806 浏览 6 评论 0原文

我有一个类型的对象集合,我想将其转换为不同类型。 这可以使用 foreach 轻松完成,但我想弄清楚如何使用 Linq 的聚合函数来完成此操作。

问题是所有聚合示例都使用行字符串或 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<>.Add 返回 void。 Aggregate 的第二个参数的返回类型需要是 List。

如果我有一个支持“+”类型语义的列表类型,我只需创建第二个参数即可

list + item

,但是我找不到任何支持此类事物的集合类型。

看起来这在 Linq 中应该很容易实现。 有办法吗? 另外,如果我缺少一种完全更简单的方法,我也很想了解这一点。 谢谢!

I have a collection of objects of one type that I'd like to convert to a different type. This can be done easily with foreach, but I'd like to figure out how to use Linq's aggregate function to do it.

The problem is all the Aggregate examples use types line string or int, which support the '+' operator. I'd like to have the accumulator type be a list, which doesn't support '+' semantics.

Here's a quick example:

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

The problem is that List<>.Add returns void. The return type of the second parameter to Aggregate needs to be a List.

If I had a list type that supported '+' type semantics I could just make the second parameter

list + item

However I can't find any collection type that supports this kind of thing.

Seems like this should be easily possible in Linq. Is there a way? Also, if I'm missing an entirely easier way, I'd love to learn about that too. Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

故人如初 2024-07-31 05:01:58

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

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

Assuming this is LINQ to Objects, try...

var newSet = set.Aggregate(new List<DestinationType>(),
                                    (list, item) =>
                                    {
                                        list.Add(new DestinationType(item.A, item.B, item.C));
                                        return list;
                                    });
回眸一笑 2024-07-31 05:01:58

我认为对 Select 的调用与 < a href="http://msdn.microsoft.com/en-us/library/bb342261.aspx" rel="noreferrer">ToList() 可能就是您所需要的。 例如:

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

I think a call to Select combined with ToList() might be what you need here. For example:

context.Items
  .Select(item => new DestinationType(item.A, item.B, item.C))
  .ToList();
百合的盛世恋 2024-07-31 05:01:58

您只需在此处应用select即可。

var newSet = set.Select(item => new DestinationType(...)).ToList();

Aggregate(通常称为foldreduce)用于将select元素组合在一起。 code> 将函数应用于每个元素。

例如:

f 是一元函数,那么
[a, b, c]。选择(f) 等于[f(a), f(b), f(c)]

f 为二元函数,然后 [a, b, c]。聚合(f, init) 等于f(a, f(b, f(c ,初始化)))

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

reversed = fold (\list element -> element:list) [] [1..10]

如果您确实想使用聚合进行此计算>,使用达斯汀的解决方案或更好地为不可变集合实现基于链表的类型(您甚至可以为该类型提供运算符+)。

You can just apply select here.

var newSet = set.Select(item => new DestinationType(...)).ToList();

Aggregate (generally known as fold or reduce) is used to combine elements together where select applies a function to each element.

Ex:

Let f be a unary function, then
[a, b, c].select(f) equals [f(a), f(b), f(c)].

Let f be a binary function, then [a, b, c].aggregate(f, init) equals f(a, f(b, f(c, init))).

The way you chose in your example is uncommon in C# but often used in functional programming where (linked) lists are transformed into new lists instead of changing an existing collection:

reversed = fold (\list element -> element:list) [] [1..10]

If you really want to do this computation with aggregate, use Dustin's solution or better implement a linked-list-based type for immutable collections (you can even give this type an operator +).

善良天后 2024-07-31 05:01:58
list.AddRange(context.Items.Select(item => 
  new DestinationType(item.A, item.B, item.C));

我意识到它不使用聚合函数,但您可能应该找到一个更好的示例来用来学习聚合。

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

I realize it doesn't use the Aggregate function, but you should probably find a better example to use to learn the aggregate.

一腔孤↑勇 2024-07-31 05:01:58

除非我遗漏了一些明显的东西,否则为什么不这样做:

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

Unless I'm missing something obvious, why not just do:

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文