【问题标题】:LINQ: how to transform list by performing calculations on every elementLINQ:如何通过对每个元素执行计算来转换列表
【发布时间】:2011-03-01 01:05:39
【问题描述】:

我有课

Class MyObject
{
    decimal v1;
    decimal dv1;
    decimal v2;
    decimal dv2;
}

还有一个

List<MyObject> ...

我需要通过将 dv1 添加到 v1 并将 dv2 添加到 v2 来处理列表的每个元素 类似于(伪语法):

myList.Transform(o=>o.v1+=o.dv1, o.v2+=o.dv2)

我该怎么做(显然我的伪语法不起作用)?

谢谢

【问题讨论】:

  • 这不是你应该用 LINQ 做的事情。 LINQ 用于执行查询(=只读)。你想改变状态。您可以为此使用一个简单的 foreach 语句。

标签: c# linq sum transform


【解决方案1】:

LINQ 用于获取给定枚举的子集或使用列表中的新类型创建枚举。

要操作给定列表,LINQ 不是操作给定列表的正确工具。要完成您的任务,您应该使用一个 foreach 循环,例如

foreach(var item in objects)
{
    item.v1 += obj.dv1;
}

您可以做的是预先选择,通过类似这样的方式从对象中选择哪些元素

foreach(var item in object.Where(o => o.v1 % 2 == 0))

像其他人提到的那样,您可以自行实现 ForEach() 扩展方法,但它不存在是有原因的:
看看Erics Blog entry

【讨论】:

  • +1。另外:LINQ is not the right tool to manipulate a given list - 我将其表述为“LINQ 是功能性的,它不应该更改原始数据,而是对其进行处理并返回结果,或者在需要时返回数据的修改副本”。跨度>
【解决方案2】:

您可以使用 List 的 ForEach 方法:

List<MyObject> objects = new List<MyObject>();

// Populate list.

objects.ForEach(obj => {
  obj.v1 += obj.dv1;
  obj.v2 += obj.dv2;
});

【讨论】:

  • ForEach方法不是Enumerable的扩展方法,而是List&lt;T&gt;的实例方法。它自 .NET 2.0 以来就一直存在。
  • 编写这样一个扩展方法很简单: public static void ForEach(this IEnumerable collection, Action action) { foreach(T item in collection) action(item ); }
  • @Ian,微不足道,但如果他已经有一个 List,则没有必要。并且可以说,最好做一个 ToList().ForEach,而不是创建一个模棱两可的扩展方法(模棱两可,因为 IEnumerable 的问题总是 when?
  • 可以说,最好简单地使用foreach
  • MoreLinq (code.google.com/p/morelinq) 在 IEnumerable 上提供了 ForEach 运算符。
【解决方案3】:

LINQ 提供'select' for transformation

list.Select( obj => new MyObject(obj.v1 + obj.dv1, obj.dv1, obj.v2 + obj.dv2, obj.dv2))

但请注意,返回值是一个新列表;原始列表的元素不会被修改。无副作用/状态突变。 如果这是您的目标,请选择 select ;否则按照其他人的建议使用 for/for-each。

【讨论】:

    【解决方案4】:

    我不认为这是 linq 的典型任务,但如果你愿意,你可以这样做:

    List<MyClass> objects = GetMyClasses();
    Func<Action<MyClas>s, bool> do = (action) => { action(); return true; }
    (from o in objects
     where do( o, b=> { b.v1 += b.dv1; b.v2 += b.dv2; } )
     select o).ToArray();
    

    【讨论】:

      【解决方案5】:

      感谢所有回答。我在想 linq 可以提供一种优雅的方式,但你是对的 - foreach 做得恰到好处。

      【讨论】:

        猜你喜欢
        • 2014-06-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-19
        • 1970-01-01
        • 2020-11-05
        • 2019-06-09
        • 1970-01-01
        相关资源
        最近更新 更多