Search code examples
c#linq

Get elements from one list which are present in first list


I am having difficult in writing code. I have a class:

public class Data 
{
    int Id { get; set; }
}

There is a list of Data.

var data = new List<Data>() 
{
    new Data() { Id = 1 },
    new Data() { Id = 2 },
    new Data() { Id = 3 }
};

Now I have two lists.

public class Val 
{
    public int Id { get; set; }
    public float Total { get; set; }
}

var listA = new List<Val>() 
{
    new Val() { Id = 1, Total = 10 },
    new Val() { Id = 2, Total = 20.0 }
}

var listB = new List<Val>() 
{
    new Val() { Id = 1, Total = 20 },
    new Val() { Id = 3, Total = 30 }
}

Now the query needs to be loop through existing list of data and get total if Id present in listA. If not present in listA, then get total for corresponding Id in listB.

In this case, sum of all total is 10+ 20 + 30 = 60.

I can write the following:

var sum = 0.0;
foreach(var item in Data)
{
    if (listA.Any(x => x.Id == item.Id)
    {
        sum += listA.FirstOrDefault(y => y.Id == item.Id).Total;
    }
    else
        Check in listB;
}

But this is not good performance wise.

Kindly help.


Solution

  • You could use dictionaries:

    // Convert lists to dictionaries
    var dictA = listA.ToDictionary(x => x.Id, x => x.Total);
    var dictB = listB.ToDictionary(x => x.Id, x => x.Total);
    
    // Use dictionary lookup instead of Any() + FirstOrDefault()
    float sum = data.Sum(d => dictA.TryGetValue(d.Id, out var totalA) 
        ? totalA
        : dictB.TryGetValue(d.Id, out var totalB) 
        ? totalB 
        : 0);