SergioCarlosFG
SergioCarlosFG

Reputation: 125

C# Compare 2 List Object and create a third

I have this class:

public class Bills
{
    public int Denom;
    public int NumberItems;
}

And two list of this class:

ListA:
 Denom:20
 NumberItems:1

ListB:
 Denom:20
 NumberItems:4,
 Denom:50
 NumberItems:2

How can I do a LINQ for made a third list whith the diference of those two list:

ListC:
 Denom:20
 NumberItems:3
 Denom:50
 NumberItems:2

I know this can be made with foreach but I think there is a better way.

Elemts in ListA will always be in ListB with the same or smaller NumberItems, but elemts in ListB possible not in ListA; no Denom repeated in each List

Here is the foreach that works for me:

        List<Bills> ListC = new List<Bills>();

        foreach (var denomB in ListB) 
        {
            bool isInListA = false;

            foreach (var denomA in ListA) 
            {
                if (denomB.Value == denomA.Value)
                {
                    Bills diference = new Bills();
                    diference.Value = denomA.Value;
                    diference.NumberItems = denomB.NumberItems - denomA.NumberItems;

                    if(diference.NumberItems > 0) ListC.Add(diference);

                    isInListA = true;
                    break;
                }
            }

            if (!isInListA)
            {
                ListC.Add(denomB);
                break;
            }
        }

Upvotes: 0

Views: 243

Answers (1)

Matt Burland
Matt Burland

Reputation: 45135

It sounds like you need a left outer join (see here). Something like this:

var listC = from b in listB join a in listA on b.Denom equals a.Denom into temp
    from t in temp.DefaultIfEmpty()
    select new Bills() { Denom = b.Denom, NumberItems = t != null ? b.NumberItems - t.NumberItems : b.NumberItems };

Here's a fiddle

The idea is to join listB with listA where Denom is equal, and then select a new Bills item with the same Denom and either the difference in NumberItems or (if it doesn't exist in listB, just the NumberItems from listB.

Now it appears from your edit that you want to remove items where NumberItems == 0, that can be easily done with a Where clause:

listC = listC.Where(c => c.NumberItems > 0);

Upvotes: 1

Related Questions