使用 LINQ 将一个对象列表属性更新为其他列表
本文关键字:列表 更新 其他 属性 使用 一个对象 LINQ | 更新日期: 2023-09-27 18:18:29
>我有一个场景,比如思考
class a
{
String Username;
String val;
}
List<a> lst = new List<a>();
List<a> lstnew = new List<a>();
我需要的是,lstnew
我在val
属性(仅在多个对象中(中有一些更新的值,我需要的是使用 LINQ 使用 LINQ 作为Username
属性lstnew
更新lst
您可以在 UserName
上联接两个列表,然后将第一个列表中的Value
更新为第二个列表中的列表。
例如,给定此类和列表:
public class a
{
public string UserName { get; set; }
public string Value { get; set; }
}
List<a> list = new List<a>
{
new a { UserName = "Perry", Value = "A" },
new a { UserName = "Ferb", Value = "B" },
new a { UserName = "Phineas", Value = "C" }
};
List<a> newList = new List<a>
{
new a { UserName = "Phineas", Value = "X" },
new a { UserName = "Ferb", Value = "Y" },
new a { UserName = "Candace", Value = "Z" }
};
您可以联接以获取具有共同UserName
的元素:
var common = from a1 in list
join a2 in newList on a1.UserName equals a2.UserName
select new { A1 = a1, A2 = a2 };
此时,如果我理解正确,您希望更新原始列表中的元素:
foreach(var c in common)
{
c.A1.Value = c.A2.Value;
}
此时,list
中的元素如下所示:
UserName Value
-----------------
Perry A
Ferb Y
Phineas X
听起来你有两个列表。 其中一个名为 lst
并包含用户名的完整列表,另一个名为 lstnew
的用户名包含已更新其val
属性的用户名列表。 我建议将未触及的用户名与已更新的用户名合并。 这是我能想到的对 LINQ 最友好的解决方案。
var updatedList = Enumerable.Union(
lst.Where(x => !lstnew.Any(y => y.Username == x.Username)),
lstnew).ToList();
您应该能够使用 .Zip()
方法来执行此操作。
lst.Zip(lstNew, (orig, new) => {
orig.Username = new.Username;
return orig;
});
您将每对放在一起的想法,然后不是返回新的,而是更改orig.Username
值并返回orig
。
这也应该可以解决问题。 由 Alastair Pitts 提出的Zip
方法假设两个集合具有相同的元素顺序,并且第一个列表中的每个元素在第二个列表中都有相应的元素。我的方法更通用,它只是通过比较属性来查找相应的元素Username
。它仍然假设对于lstNew
中的每个元素,lst
中都有相应的元素。
lstNew.ForEach(new => lst.First(orig => orig.Username == new.Username).val = new.val);
这是一个老问题,但我开发了一个更优雅的解决方案,这比@JeffOgata给出的解决方案略有改进:
var newList= lst.GroupJoin(lstnew ,
i => i.UserName ,
j => j.UserName ,
(i, j) => j.FirstOrDefault()?? i );
其中lst
是原始列表,lstnew
是新列表。
这将只是将第一个列表中的整个对象替换为第二个列表中的相应对象(如果存在(。这比@JeffOgata给出的答案略有改进
结果是一样的。
如果您有复杂的对象,那么遍历每个对象然后遍历所有属性是一个问题,简单地用新对象替换旧对象会更快。
希望这会帮助某人。