Lambda 表达式 - 根据集合中另一个属性的值设置对象集合中一个属性的值

Posted

技术标签:

【中文标题】Lambda 表达式 - 根据集合中另一个属性的值设置对象集合中一个属性的值【英文标题】:Lambda expressions - set the value of one property in a collection of objects based on the value of another property in the collection 【发布时间】:2011-02-24 08:20:10 【问题描述】:

我是 lambda 表达式的新手,希望利用该语法根据集合中的另一个值设置集合中一个属性的值

通常我会做一个循环:

class Item

    public string Name  get; set; 
    public string Value  get; set; 


void Run()

    Item item1 = new Item  Name = "name1" ;
    Item item2 = new Item  Name = "name2" ;
    Item item3 = new Item  Name = "name3" ;

    Collection<Item> items = new Collection<Item>()  item1, item2, item3 ;

    // This is what I want to simplify.
    for (int i = 0; i < items.Count; i++)
    
        if (items[i].Name == "name2")
        
            // Set the value.
            items[i].Value = "value2";
        
    

【问题讨论】:

【参考方案1】:

LINQ 通常对于选择数据比修改数据更有用。但是,你可以这样写:

foreach(var item in items.Where(it => it.Name == "name2")) 
  item.Value = "value2";

这首先选择需要修改的项目,然后使用标准的命令式循环修改所有项目。您可以将 foreach 循环替换为可用于列表的 ForAll 方法,但我认为这不会给您带来任何优势:

items.Where(it => it.Name == "name2").ToList()
     .ForEach(it => it.Value = "value2");

请注意,您需要在中间添加 ToList,因为 ForEach 是 .NET 2.0 功能,仅适用于 List&lt;T&gt; 类型 - 并非适用于所有 IEnumerable&lt;T&gt; 类型(与其他 LINQ 方法一样)。如果你喜欢这种方法,你可以为IEnuerable&lt;T&gt;实现ForEach

public static void ForEach<T>(this IEnumerable<T> en, Action<T> f) 
  foreach(var a in en) f(a);


// Then you can omit the `ToList` conversion in the middle 
items.Where(it => it.Name == "name2")
     .ForEach(it => it.Value = "value2");

无论如何,我更喜欢foreach 循环,因为这也清楚地表明您正在做一些突变 - 在代码中轻松看到这一事实很有用。

【讨论】:

漂亮。那么没有办法绕过循环了吗? @Michael Rut,循环读取比 ForEach 方法更好,但这是一个见仁见智的问题。我同意托马斯在回答中关于行动的明确性所说的话。然而,他确实为您展示了一种抽象循环的方法(尽管显然循环仍然会发生,而不是您明确编码它与否)。 如果我想在设置值后更新 db,哪一个更适合对 db 的影响较小? 性能将是相同的——它们都会生成相同数量的UPDATE 语句(当您提交更改时)。

以上是关于Lambda 表达式 - 根据集合中另一个属性的值设置对象集合中一个属性的值的主要内容,如果未能解决你的问题,请参考以下文章

java 集合存储对象且根据对象属性排序

Java8 Lambda 表达式

Java8 Lambda 表达式

Java8 Lambda 表达式

java Lambda表达式

Java通过Lambda表达式根据指定字段去除重复数据(集合去重)