我有一个思考的场景
class a
{
String Username;
String val;
}
List<a> lst = new List<a>();
List<a> lstnew = new List<a>();
我需要的是lstnew
我在val
属性(仅限多个对象)中有一些更新值,我需要的是更新{{ 1}}使用 LINQ
lst
中的更新值作为lstnew
属性
答案 0 :(得分:8)
您可以在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 };
s:
foreach(var c in common)
{
c.A1.Value = c.A2.Value;
}
此时,如果我理解正确,您想要更新原始列表中的元素:
list
此时UserName Value
-----------------
Perry A
Ferb Y
Phineas X
中的元素如下所示:
{{1}}
答案 1 :(得分:3)
听起来你有两个清单。其中一个名为lst
,包含完整的用户名列表,另一个名为lstnew
,其中包含已更新val
属性的用户名列表。我建议将未经修改的用户名与已更新的用户名联合起来。这代表了我能想到的最符合LINQ的解决方案。
var updatedList = Enumerable.Union(
lst.Where(x => !lstnew.Any(y => y.Username == x.Username)),
lstnew).ToList();
答案 2 :(得分:1)
您应该能够使用.Zip()
方法执行此操作。
lst.Zip(lstNew, (orig, new) => {
orig.Username = new.Username;
return orig;
});
您想要将每对配对在一起,然后更改orig.Username
值并返回orig
,而不是返回新配对。
答案 3 :(得分:0)
这也应该可以解决问题。由Alastair Pitts提出的Zip
方法假设两个集合具有相同的元素顺序,并且第一个列表中的每个元素在第二个列表中具有对应元素。我的方法更通用,它只是通过比较Username
属性来查找相应的元素。仍然假设lstNew
中的每个元素都在lst
中有相应的元素。
lstNew.ForEach(new => lst.First(orig => orig.Username == new.Username).val = new.val);
答案 4 :(得分:0)
我知道这是一个老问题,但是我开发的一个更优雅的解决方案,比@JeffOgata给出的稍微改进一点:
var newList= lst.GroupJoin(lstnew ,
i => i.UserName ,
j => j.UserName ,
(i, j) => j.FirstOrDefault()?? i );
lst
是原始列表,lstnew
是新列表。
这将只用第二个列表中的相应对象(连接)替换第一个列表中的整个对象(如果存在)。 这比@JeffOgata
给出的答案略有改进结果是一样的。
如果您有复杂的对象,那么遍历每个对象然后遍历所有属性是一个问题,只需用新的对象替换旧对象就更快了。
这有望帮助某人。