tags:

views:

33

answers:

1

Ok, I'm trying to get this working. This is my first time using LINQ. So far it's ok except a little snag that I've been trying to figure out.

Scenario: I have 2 generic lists I'm sending to a method. That method has this in it below to give me back a list of only those objects (union) where a certain ID is found in both. The lists could have different lengths and different order of IDs. The goal or what I want to do is get back from comparing those 2 lists, a list of objects where both have the same IDs. But furthermore when I find a matched object in both those lists (by id) don't give me back that object yet unless the call to OptionsMatch is also true (so that's why I have the &&).

The main problem I've had is that the lists can be totally different in length and have even differences in the list of IDs. But we know that all the lists we are passing to my method will have some commonality in terms of some of those objects will match by ID...no matter what lenth or order the 2 lists we are comparing are...we want the union of the lists back but only if also the call to OptionsMatch for that matched set of IDs match also.

Here's my LINQ statement (original)

List<SavedItemOption> finalItemOptions = savedItemOptions.Where(y => itemOptions.All(x => OptionsMatch(x,y) && (y.actID == x.Id))).ToList();

I've recently changed it to this:

List finalItemOptions = savedItemOptions.Where(y => (y.actID == x.Id) && itemOptions.All(x => OptionsMatch(x,y))).ToList();

but again, the problem is, LINQ is comparing the first Id in y with every other id in x. That's great. Take the first y.actID and look through all of x's x.ID. But then it stops. It doesn't then move to next savedItemOptions index and compare y.actID to all of x's x.IDs again.

+1  A: 

That's really easy - just change the order in your expression:

List<SavedItemOption> finalItemOptions = savedItemOptions
    .Where(y => itemOptions.Any(x => y.actID == x.Id && OptionsMatch(x,y)))
    .ToList();

That relies on C#'s short-circuiting of the && operator - if the LHS returns false, the RHS isn't evaluated.

Another option would be to use a join:

var finalItemOptions = (from y in savedItemOptions
                        join x in itemOptions on y.actID equals x.Id
                        where OptionsMatch(x, y)
                        select y).ToList();
Jon Skeet
still doesn't work. it's moving in a forward fashion between 2 lists and so the first time around, the IDs jsut happen to match on sure luck that they were the first in the 2 lists. However once it iterated and checked the 2nd set of IDs in the lists the IDs are different so it never hits my MatchOptions method.
CoffeeAddict
@coffeeaddict: I'm afraid I can't really understand exactly the situation you're seeing. It would be *much* simpler if you could include a short but complete program to reproduce the problem. The code I've given *will* only invoke OptionsMatch for items with the same ID, and should find those items if they're present...
Jon Skeet
see the updated comment to the original post...
CoffeeAddict
Jon you're right on with what I'm trying to do.
CoffeeAddict
the 2nd way you showed using the join works great. Not sure why we can't get the first to do the same. Weird.
CoffeeAddict