Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using lambda expressions to get a subset where array elements are equal

Tags:

c#

lambda

I have an interesting problem, and I can't seem to figure out the lambda expression to make this work.

I have the following code:

List<string[]> list = GetSomeData(); // Returns large number of string[]'s
List<string[]> list2 = GetSomeData2(); // similar data, but smaller subset
&nbsp;
List<string[]> newList = list.FindAll(predicate(string[] line){ 
    return (???);
});

I want to return only those records in list in which element 0 of each string[] is equal to one of the element 0's in list2.

list contains data like this:

"000", "Data", "more data", "etc..."

list2 contains data like this:

"000", "different data", "even more different data"

Fundamentally, i could write this code like this:

List<string[]> newList = new List<string[]>();
foreach(var e in list)
{
    foreach(var e2 in list2)
    {
        if (e[0] == e2[0])
            newList.Add(e);
    }
}
return newList;

But, i'm trying to use generics and lambda's more, so i'm looking for a nice clean solution. This one is frustrating me though.. maybe a Find inside of a Find?

EDIT: Marc's answer below lead me to experiment with a varation that looks like this:

var z = list.Where(x => list2.Select(y => y[0]).Contains(x[0])).ToList();

I'm not sure how efficent this is, but it works and is sufficiently succinct. Anyone else have any suggestions?

like image 425
Erik Funkenbusch Avatar asked Feb 15 '09 09:02

Erik Funkenbusch


1 Answers

You could join? I'd use two steps myself, though:

var keys = new HashSet<string>(list2.Select(x => x[0]));
var data = list.Where(x => keys.Contains(x[0]));

If you only have .NET 2.0, then either install LINQBridge and use the above (or similar with a Dictionary<> if LINQBridge doesn't include HashSet<>), or perhaps use nested Find:

var data = list.FindAll(arr => list2.Find(arr2 => arr2[0] == arr[0]) != null);

note though that the Find approach is O(n*m), where-as the HashSet<> approach is O(n+m)...

like image 164
Marc Gravell Avatar answered Nov 14 '22 21:11

Marc Gravell