我有一些列表(其中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循环,它只做更改,但它不会删除任何项目)。
答案 0 :(得分:93)
您可以使用ForEach
,但必须先将IEnumerable<T>
转换为List<T>
。
list.Where(w => w.Name == "height").ToList().ForEach(s => s.Value = 30);
答案 1 :(得分:10)
我可能会选择这个(我知道它不是纯粹的linq),如果你想保留所有项目,请保留对原始列表的引用,你应该发现更新的值在那里:
foreach (var mc in list.Where(x => x.Name == "height"))
mc.Value = 30;
答案 2 :(得分:3)
list.Find(x => x.Name == "height").Value = 20;
怎么样
这很好用。我知道它是一个旧帖子,但只是想知道为什么没有人建议这个?这段代码有缺点吗?
答案 3 :(得分:2)
您可以使用带有语句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();
答案 4 :(得分: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子句即可。
答案 5 :(得分:0)
我知道这是一篇老文章,但是,我一直使用更新程序扩展方法:
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);
答案 6 :(得分:-2)
您可以这样做:
var newList = list.Where(w => w.Name == "height")
.Select(s => new {s.Name, s.Value= 30 }).ToList();
但我宁愿选择使用foreach
,因为LINQ
用于查询
想要编辑数据。