views:

225

answers:

4

I have two lists I need to form the union of, but I'm in .NET 2.0 so the Union() method appears to be out. These are lists of integers, so no problem with the equality comparisons. What's a good way to go about this?

+3  A: 

You could just add them together and remove the duplicates:

  public List<T> Union<T>(List<T> firstList, List<T> secondList)
  {
     Dictionary<T, int> tmp = new Dictionary<T, int>();

     foreach (T val in firstList)
     {
        tmp[val] = 1;
     }

     foreach (T val in secondList)
     {
        tmp[val] = 1;
     }

     return new List<T>(tmp.Keys);
  }
SwDevMan81
Using a dictionary may change the order of the elements in the list.
CodeSavvyGeek
And will alter firstList as a side-effect of the operation
thecoop
@CodeSavvyGeek Union of two sets by definition is associative and commutative, order doesn't matter.
SwDevMan81
@thecoop Update the example
SwDevMan81
There's no need for combined_list - you can just stick firstList and secondList straight into the dictionary
thecoop
+1  A: 

How about a simple foreach, only adding elements that aren't already in the list:

foreach (int item in list2)
{
    if (!list1.Contains(item))
    {
        list1.Add(item);
    }
}

This will preserve the order of the lists.

CodeSavvyGeek
Contains could be slow if the lists are large.
SwDevMan81
+1  A: 

You could use linqbridge to let you use LINQ to Objects while still targeting Framework 2.0, if you have Visual Studio 2008.

And push, push, push to move to .NET 3.5. LINQ and lambdas change the way you think about code (for the better, IMHO).

TrueWill
We can't use .NET 3.5 yet on our packaged software, as some people may not have installed it yet (think XP machines run by a BOFH)
thecoop
+2  A: 

What about (using Dictionary keys as a hashtable):

public static List<T> Union<T>(List<T> first, List<T> second) {
    List<T> newList = new List<T>(first.Count + second.Count);
    Dictionary<T, object> firstItems = new Dictionary<T, object>(first.Count);

    foreach (T item in first) {
        newList.Add(item);
        firstItems.Add(item, null); 
    }

    foreach (T item in second) {
        if (!firstItems.ContainsKey(item) {
            newList.Add(item);
        }
    }

    return newList;
}

This will maintain the item order in first and second, while still using an O(1) check for duplicate items between the lists

thecoop
Good ideas here, thanks to everyone for their contributions!
larryq
Just note this wont remove dups in first
SwDevMan81