listOne
.Join(listTwo,
x => x.key,
y => y.key,
(x, y) =>
{
y.SomeProperty = x.SomeProperty;
return 0;
});
我需要将一个属性从一个列表复制到另一个列表中的项目匹配,我可以轻松加入两个列表,如上面的示例所示,但我认为另一个开发人员会跟我说“哎呀?”因为我并没有按照预期的方式使用它。 linq是否提供了更合适的方法来完成同样的事情?
或者如果我希望我的代码可读,我应该坚持使用循环而不是尝试一行吗?
答案 0 :(得分:0)
我个人更喜欢返回一个新列表的更实用的方法,但是如果你设置这个改变另一个列表,那么你可以做以下几个至少意味着副作用(通过ForEach
):
val keyMatchedList= from x in listOne
join y in listTwo on x.key == y.key
select new {x.key, y.SomeProperty};
listTwo.ForEach(
x=> x.SomeProperty = keyMatchedList.First(y=>y.Key == x.Key).SomeProperty);
但是,请记住,LINQ是一种无副作用的尝试......
答案 1 :(得分:0)
请注意,ParallelEnumerable<T>
和List<T>
提供了针对每个结果执行Action<T>
的方法,但这些是特定的可枚举类型,可能不适合这种情况(旁注:考虑并行)对于这种特殊情况,请.AsParallel()
)
但是,默认实现是执行循环而不是使用传递给Func
或Join
的{{1}},如您所说,它可能会产生误导并且需要使用回报价值。用Justin Pihony的答案来表达这一点,这违反了“无副作用”的原则。
这是您应该考虑使用匿名类型的确切说明,如此
Select
更详细,但避免滥用方法,以某种方式可能会让某人不得不做双击。
另请注意,虽然在Linq中没有为您完成,但可以编写您自己的foreach(var pair in listOne
.Join(listTwo,
x => x.key,
y => y.key,
(x, y) => new { first = x, second = y}))
{
pair.first.SomeProperty = pair.second.SomeProperty;
}
ForEach
使用同样的方法,建议偶尔为IEnumerables编写自己的扩展方法(我特别喜欢让public static void ForEach<T>(this IEnumerable<T> source, Action<T> act)
{
foreach(T t in source) act(t);
}
更新UpdateCollecitonTo
中的项目而不仅仅是替换引用。 ..)为此,在参考源
ObservableCollection
的源coe可能会有所帮助