Yippie-Ki-Yay
Yippie-Ki-Yay

Reputation: 22814

C# linq union question

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

Upvotes: 11

Views: 12657

Answers (3)

Thomas Levesque
Thomas Levesque

Reputation: 292405

You can use second.Union(first) instead of first.Union(second). That way, it will keep the items from second rather than the items from first.

Upvotes: 16

CodesInChaos
CodesInChaos

Reputation: 108790

When the object returned by this method is enumerated, Union enumerates first and second in that order and yields each element that has not already been yielded.
http://msdn.microsoft.com/en-us/library/bb341731.aspx

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 consistent Equals and GetHashCode. And in this case I prefer to explicitly supply an equality comparer to the union method instead of having the Equals of the object itself return true for objects which are not identical for all purposes.

Upvotes: 9

ChrisF
ChrisF

Reputation: 137128

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 use sequence1.Union(sequence2) or sequence2.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.

Upvotes: 5

Related Questions