3

What is a simple effective way to take List2 and add it to the end of List1 - but in a way that only those items that are not already in List1 before the concatenation - will be added to it?

EDIT: I've been trying methods suggested in answers here, but I still get dupes added to List1!
This is a code example:

// Assume the existence of a class definition for 'TheObject' which contains some 
// strings and some numbers.

string[] keywords = {"another", "another", "another"};
List<TheObject> tempList = new List<TheObject>();
List<TheObject> globalList = new List<TheObject>();

foreach (string keyword in keywords)
{
    tempList = // code that returns a list of relevant TheObject(s) according to
               // this iteration's keyword.
    globalList = globalList.Union<TheObject>(tempList).ToList();
}

When debugging - after the second iteration - globalList contain two copies of the exact same object of TheObject. Same thing happens also when I try implementing Edward Brey's solution...

EDIT2:
I've modified the code that returns a new tempList, to also check if the returned items are already in the globalList (by doing !globalList.contains()) - it works now.
Though, this is a work-around...

Yuval A.
  • 5,849
  • 11
  • 51
  • 63
  • Does TheObject have Equals overridden? Otherwise, the default is reference equality, which won't work if tempList's items are newly created each time. – Edward Brey Apr 16 '12 at 05:17
  • It's a class auto-generated by Linq to SQL from a table in a DB. I looked at the definition and haven't seen any Equals override. Should I create one? One that takes two object instances and compare each of their properties? – Yuval A. Apr 16 '12 at 05:27
  • Or can I somehow change this default of 'by reference equality' to 'by value'? – Yuval A. Apr 16 '12 at 05:29
  • 1
    Assuming you don't have duplicates in your starting `globalList`, you can use `Union` overload with the extra parameter and put the value comparison semantics in the class you derive from `IEqualityComparer`. – Edward Brey Apr 16 '12 at 05:42

3 Answers3

4

List1.Union(list2).For more examples goto http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b

Krishnanunni Jeevan
  • 1,719
  • 1
  • 15
  • 24
2

You can use the List's Union method like

List1.Union(list2);
Scorpion-Prince
  • 3,574
  • 3
  • 18
  • 24
1

LINQ's Union will work if all of List1's items are distinct. Otherwise, to more precisely meet the stated goal, without requiring O(m*n) search time, you can use a hash set (replace T with the type of your list):

var intersection = new HashSet<T>(List1.Intersect(List2));
List1.AddRange(List2.Where(item => !intersection.Contains(item)));
Edward Brey
  • 40,302
  • 20
  • 199
  • 253