[c#] Intersect Two Lists in C#

I have two lists:

  List<int> data1 = new List<int> {1,2,3,4,5};
  List<string> data2 = new List<string>{"6","3"};

I want do to something like

var newData = data1.intersect(data2, lambda expression);

The lambda expression should return true if data1[index].ToString() == data2[index]

This question is related to c# intersection

The answer is


You need to first transform data1, in your case by calling ToString() on each element.

Use this if you want to return strings.

List<int> data1 = new List<int> {1,2,3,4,5};
List<string> data2 = new List<string>{"6","3"};

var newData = data1.Select(i => i.ToString()).Intersect(data2);

Use this if you want to return integers.

List<int> data1 = new List<int> {1,2,3,4,5};
List<string> data2 = new List<string>{"6","3"};

var newData = data1.Intersect(data2.Select(s => int.Parse(s));

Note that this will throw an exception if not all strings are numbers. So you could do the following first to check:

int temp;
if(data2.All(s => int.TryParse(s, out temp)))
{
    // All data2 strings are int's
}

If you have objects, not structs (or strings), then you'll have to intersect their keys first, and then select objects by those keys:

var ids = list1.Select(x => x.Id).Intersect(list2.Select(x => x.Id));
var result = list1.Where(x => ids.Contains(x.Id));

public static List<T> ListCompare<T>(List<T> List1 , List<T> List2 , string key )
{
    return List1.Select(t => t.GetType().GetProperty(key).GetValue(t))
                .Intersect(List2.Select(t => t.GetType().GetProperty(key).GetValue(t))).ToList();
}

From performance point of view if two lists contain number of elements that differ significantly, you can try such approach (using conditional operator ?:):

1.First you need to declare a converter:

Converter<string, int> del = delegate(string s) { return Int32.Parse(s); };

2.Then you use a conditional operator:

var r = data1.Count > data2.Count ?
 data2.ConvertAll<int>(del).Intersect(data1) :
 data1.Select(v => v.ToString()).Intersect(data2).ToList<string>().ConvertAll<int>(del);

You convert elements of shorter list to match the type of longer list. Imagine an execution speed if your first set contains 1000 elements and second only 10 (or opposite as it doesn't matter) ;-)

As you want to have a result as List, in a last line you convert the result (only result) back to int.