22

i have a question about how to do a common programming task in linq.

lets say we have do different collections or arrays. What i would like to do is match elements between arrays and if there is a match then do something with that element.

eg:

        string[] collection1 = new string[] { "1", "7", "4" };
        string[] collection2 = new string[] { "6", "1", "7" };

        foreach (string str1 in collection1)
        {
            foreach (string str2 in collection2)
            {
                if (str1 == str2)
                {
                    // DO SOMETHING EXCITING///
                }
            }
        }

This can obviously be accomplished using the code above but what i am wondering if there is a fast and neat way you can do this with LinqtoObjects?

Thanks!

Grant
  • 11,138
  • 32
  • 94
  • 140
  • That wold depend on implementation of // DO SOMETHING EXCITING/// It may not even be possible, because Ling is heavily IEnumerable-based, while this code can do whatever. Linq builds a data structure for you. What does // DO SOMETHING EXCITING/// do? – Hamish Grubijan Jan 25 '10 at 02:11
  • And by the way, you can reduce O(n^2) down to O(n) by using two instances of a set data structure. – Hamish Grubijan Jan 25 '10 at 02:12

2 Answers2

32

Yes, intersect - Code sample to illustrate.

string[] collection1 = new string[] { "1", "7", "4" };
string[] collection2 = new string[] { "6", "1", "7" };

var resultSet = collection1.Intersect<string>(collection2);

foreach (string s in resultSet)
{
    Console.WriteLine(s);
}
Ragepotato
  • 1,630
  • 11
  • 13
  • Intersect is the cleanest, but why did you use the name 'union'? – Hamish Grubijan Jan 25 '10 at 02:14
  • 10
    Cause I was watching the Saints - Vikings game and was slightly distracted. Good point - I'll edit it – Ragepotato Jan 25 '10 at 02:17
  • 1
    what about if the collections were different classes where classa.string needed to match classb.string – Grant Jan 25 '10 at 02:28
  • In Python you can sometimes supply a lambda, sort of like this: m = min(coll, key = lambda x: x.field1). What this does is it computes the minimum element with the minimum value named 'field1'. I think Lambdas are used with Linq as well. I am not an expert in this, but it would be nice if Intersect took a lambda as an optional parameter. – Hamish Grubijan Jan 25 '10 at 02:36
  • Forgot to mention, that in Python you can also supply a cmp parameter to min: m = min(coll, cmp = lambda x,y: x.field1 - y.field1) - should achieve the same result. You can hink of other uses for cmp=, I am sure. – Hamish Grubijan Jan 25 '10 at 02:38
13

If you want to execute arbitrary code on matches then this would be a LINQ-y way to do it.

var query = 
   from str1 in collection1 
   join str2 in collection2 on str1 equals str2
   select str1;

foreach (var item in query)
{
     // do something fun
     Console.WriteLine(item);
}
Sam
  • 6,167
  • 30
  • 39