C# linq 联合问题
有人可以解释一下 LINQ 中的 Union 是如何工作的吗?
据说它会合并两个序列并删除重复项。
但是我可以以某种方式自定义重复项删除行为 - 假设我希望使用第二个序列
中的元素重复的情况或来自第一个序列
。
或者即使我希望以某种方式将这些值组合到结果序列中?
应该如何实现?
更新
我想我错误地描述了问题,假设我们有一些价值:
class Value {
String name
Int whatever;
}
并且使用的比较器执行 x.name == y.name
查看。
假设有时我知道应该从第二个序列中获取元素,因为它的 whatever
字段比第一个序列的 whatever
字段更新/更好。
无论如何,我会使用方法的 sequence1.Union(sequence2)
或 sequence2.Union(sequence1)
变体。
谢谢
Could someone explain how does Union
in LINQ work?
It is told that it merges two sequences and removes duplicates.
But can I somehow customize the duplicate removal behavior - let's say if I wish to use the element from the second sequence
in case of duplicate or from the first sequence
.
Or even if I wish to somehow combine those values in the resulting sequence?
How should that be implemented?
Update
I guess I described the problem incorrectly, let's say we have some value:
class Value {
String name
Int whatever;
}
and the comparer used performs a x.name == y.name
check.
And let's say that sometimes I know I should take the element from the second sequence, because it's whatever
field is newer / better than the whatever
field of the first sequence.
Anyway, I would use the sequence1.Union(sequence2)
or sequence2.Union(sequence1)
variation of the methods.
Thank you
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以使用
second.Union(first)
而不是first.Union(second)
。这样,它将保留second
中的项目,而不是first
中的项目。You can use
second.Union(first)
instead offirst.Union(second)
. That way, it will keep the items fromsecond
rather than the items fromfirst
.所以无论用作左参数的序列中的元素都优先于右参数中的元素。
重要的是它有明确定义和记录的行为,而不仅仅是在 .net 的下一版本中可能更改的实现细节。
顺便说一句,当您实现
IEqualityComparer
时,使用一致的Equals
和GetHashCode
非常重要。在这种情况下,我更喜欢显式地向 union 方法提供一个相等比较器,而不是让对象本身的Equals
对于并非所有目的都相同的对象返回true
。So the elements from whichever sequence you use as the left parameter take precedence over the elements from right parameter.
The important thing about this is that it's well defined and documented behavior and not just an implementation detail that might change in the next version of .net.
As a side-note when you implement an
IEqualityComparer<T>
it's important to use consistentEquals
andGetHashCode
. And in this case I prefer to explicitly supply an equality comparer to the union method instead of having theEquals
of the object itself returntrue
for objects which are not identical for all purposes.如果元素是重复的,那么它们来自哪个列表并不重要 - 除非您的相等比较器当然不考虑元素的所有属性。
如果它们不是真正重复的,那么它们都会出现在生成的联合中。
更新
至少根据您的新信息,您应该编写一个新的等式运算符,将
whatever
考虑在内。您不能只使用sequence1.Union(sequence2)
或sequence2.Union(sequence1)
除非所有元素都想从一个序列中获取,或者另一个。在极端情况下,您必须编写自己的
Union
扩展方法来为您完成此操作。If the elements are duplicates then it doesn't matter which list they are taken from - unless your equality comparer doesn't take all properties of the element into account of course.
If they aren't really duplicates then they'll both appear in the resultant union.
UPDATE
From your new information at the minimum you should write a new equality operator that takes
whatever
into account. You can't just usesequence1.Union(sequence2)
orsequence2.Union(sequence1)
unless all the elements want taking from one sequence or the other.At the extreme you'll have to write your own
Union
extension method which does this for you.