64

我有一些列表(其中 T 是一个自定义类,并且类有一些属性)。我想知道如何使用 Lambda 表达式更改其中的一个或多个值,因此结果将与下面的 foreach 循环相同:

注意:列表中包含多个项目(多行)

        foreach (MyClass mc in list)  
        {
            if (mc.Name == "height")
                mc.Value = 30;
        }

这是 linq 查询(使用 Lambda 表达式),但它与上面的 foreach 循环不同,它只返回列表中的 1 项(一行)!

我想要的是,它返回所有项目(所有行)并且只更改适当的项目(在 WHERE 扩展方法中指定的项目。

list = list.Where(w => w.Name == "height").Select(s => { s.Value = 30; return s; }).ToList();

注意:这两个例子不一样!我再说一遍,linq 只返回 1 个项目(一行),这是我不想要的,我也需要列表中的所有项目(比如 foreach 循环,它只做更改,但它不会删除任何项目)。

4

7 回答 7

132

您可以使用ForEach,但您必须将 转换IEnumerable<T>List<T>第一个。

list.Where(w => w.Name == "height").ToList().ForEach(s => s.Value = 30);
于 2012-10-20T08:43:33.650 回答
13

我可能会选择这个(我知道它不是纯 linq),如果您想保留所有项目,请保留对原始列表的引用,并且您应该在那里找到更新的值:

 foreach (var mc in list.Where(x => x.Name == "height"))  
     mc.Value = 30;
于 2012-10-20T09:06:30.550 回答
5

您可以使用带有语句 lambda 的投影,但原始foreach循环更具可读性,并且正在就地编辑列表而不是创建新列表。

var result = list.Select(i => 
   { 
      if (i.Name == "height") i.Value = 30;
      return i; 
   }).ToList();

扩展方法

public static IEnumerable<MyClass> SetHeights(
    this IEnumerable<MyClass> source, int value)
{
    foreach (var item in source)
    {
       if (item.Name == "height")
       {
           item.Value = value;
       }

       yield return item;
    } 
}

var result = list.SetHeights(30).ToList();
于 2012-10-20T08:45:11.187 回答
3

怎么样list.Find(x => x.Name == "height").Value = 20; 这工作正常。我知道它是一个旧帖子,但只是想知道为什么没有人建议这个?这段代码有缺点吗?

于 2017-08-24T09:45:44.863 回答
2

我会这样做:说“列表”是一个 <List<t>>其中 t 是具有名称和值字段的类;但当然你可以用任何其他类类型来做到这一点。

    list = list.Where(c=>c.Name == "height")
        .Select( new t(){Name = c.Name, Value = 30})
        .Union(list.Where(c=> c.Name != "height"))
        .ToList();

这完美!这是一个没有任何循环逻辑的简单 linq 表达式。您唯一应该注意的是,结果数据集中的行顺序与源数据集中的顺序不同。因此,如果排序对您很重要,只需在最终的 linq 查询中重现相同的 order by 子句。

于 2020-05-21T09:50:01.823 回答
-1

我知道这是一篇旧帖子,但我一直使用更新程序扩展方法:

      public static void Update<TSource>(this IEnumerable<TSource> outer, Action<TSource> updator)
        {
            foreach (var item in outer)
            {
                updator(item);
            }
        }

list.Where(w => w.Name == "height").ToList().Update(u => u.height = 30);

于 2020-11-10T09:10:46.400 回答
-2

你可以这样做:

var newList = list.Where(w => w.Name == "height")
              .Select(s => new {s.Name, s.Value= 30 }).ToList();

但我宁愿选择使用foreach,因为LINQ它用于在您想要编辑数据时进行查询。

于 2012-10-20T08:51:17.527 回答