有人可以解释LINQ中Union
的工作原理吗?
据说它合并了两个序列,删除了重复项。
但我可以以某种方式自定义重复删除行为 - 假设我希望在重复或来自the second sequence
的情况下使用the first sequence
中的元素。
或者即使我希望以某种方式在结果序列中组合这些值?
应如何实施?
我想我错误地描述了这个问题,让我们说我们有一些价值:
class Value {
String name
Int whatever;
}
并且使用的比较器执行x.name == y.name
检查。
让我们说有时我知道我应该从第二个序列中取出元素,因为它的whatever
字段比第一个序列的whatever
字段更新/更好。
无论如何,我会使用方法的sequence1.Union(sequence2)
或sequence2.Union(sequence1)
变体。
谢谢
答案 0 :(得分:13)
您可以使用second.Union(first)
代替first.Union(second)
。这样,它会保留second
中的项目,而不是来自first
的项目。
答案 1 :(得分:7)
当枚举此方法返回的对象时,Union按该顺序枚举第一个和第二个,并产生尚未产生的每个元素。
http://msdn.microsoft.com/en-us/library/bb341731.aspx
因此,用作左参数的任何序列的元素优先于右参数的元素。
关于这一点的重要之处在于,它是明确定义和记录的行为,而不仅仅是在下一版.net中可能会改变的实现细节。
作为实施IEqualityComparer<T>
时的旁注,使用一致的Equals
和GetHashCode
非常重要。在这种情况下,我更喜欢明确地为union方法提供一个相等比较器,而不是让对象本身的Equals
返回true
对于所有目的都不相同的对象。
答案 2 :(得分:5)
如果元素是重复的,那么它们取自哪个列表并不重要 - 除非您的相等比较器当然没有考虑元素的所有属性。
如果它们不是真的重复,那么它们都会出现在结果联盟中。
<强>更新强>
至少从您的新信息中,您应该编写一个新的等于运算符,并将whatever
考虑在内。您不能只使用sequence1.Union(sequence2)
或sequence2.Union(sequence1)
,除非所有元素需要从一个序列或另一个序列中获取。
在极端情况下,您必须编写自己的Union
扩展方法,为您执行此操作。