r3plica
r3plica

Reputation: 13367

Function to linq conversion

I have a function which I believe can be simplified into LINQ but have been unable to do so yet. The function looks like this:

private IList<Colour> GetDifference(IList<Colour> firstList, IList<Colour> secondList)
{

    // Create a new list
    var list = new List<Colour>();

    // Loop through the first list
    foreach (var first in firstList)
    {

        // Create a boolean and set to false
        var found = false;

        // Loop through the second list
        foreach (var second in secondList)
        {

            // If the first item id is the same as the second item id
            if (first.Id == second.Id)
            {

                // Mark it has being found
                found = true;
            }
        }

        // After we have looped through the second list, if we haven't found a match
        if (!found)
        {

            // Add the item to our list
            list.Add(first);
        }
    }

    // Return our differences
    return list;
}

Can this be converted to a LINQ expression easily?

Upvotes: 0

Views: 74

Answers (2)

Charles Mager
Charles Mager

Reputation: 26213

What is Colour? If it overrides Equals to compare by Id then this would work:

firstList.Except(secondList);

If Colour does not override Equals or it would be wrong for you to do so in the wider context, you could implement an IEqualityComparer<Colour> and pass this as a parameter:

firstList.Except(secondList, comparer);

See the documentation

As noted in the comments below, Except has the added side effect of removing any duplicates in the source (firstList in this example). This may or may not be an issue to you, but should be considered.

If keeping any duplicates in firstList is of importance, then this is the alternative:

var secondSet = new HashSet<Colour>(secondList, comparer);
var result = firstList.Where(c => !secondSet.Contains(c));

As before, comparer is optional if Colour implements appropriate equality

Upvotes: 3

H W
H W

Reputation: 2586

try the following:

var result = firstList.Where(x => !secondList.Any(y => y.ID == x.ID));

Edit: If you care about runtime and don't mind creating your own IEqualityComparer<>, i would suggest you use Except like Charles suggested in his answer. Except seems to use a hashtable for the second list which speeds it up quite a bit compared to my O(n*m) query. However be aware that Except removes duplicates from secondList as well.

Upvotes: 3

Related Questions