Terence
Terence

Reputation: 662

how to turn nested foreach loop with C# linq

I have a private method as follow:

private Dictionary<string, decimal> GetRateByYear(IEnumerable<EmployerCu> cuList, 
    HashSet<long> activeCuSet, int year)
{
    Dictionary<string, decimal> cuDict = new Dictionary<string, decimal>();
    foreach (EmployerCu cu in cuList)
    {
        decimal rate = 0;    // rate maintains 0 if year is not match

        if (activeCuSet.Contains(cu.PayrollClassId))    // ignore inactive CUs
        {
            foreach (Rate r in cu.Rates)
            {
                if (r.Year == year)
                {
                    rate =  r.Value / Percentile;
                }
            }

            cuDict.Add(cu.Code.ToString(), rate);
        }        
    }

    return cuDict;
}

The logic works as expected. I just wanna challenge myself a little bit more with C# Linq. I am trying to filter the input "cuList" with "activeCuSet", and add the cu.code and the rate for this year in a dictionary.

Here is the data model:

public class EmployerCu
{
    public long ClassId { get; set; }
    public long Code { get; set; }
    public string Name { get; set; }
    public long PayrollClassId { get; set; } 
    public Rate[] Rates { get; set; }
}

public class Rate
{
    public RateType Type { get; set; }
    public decimal Value { get; set; }
    public long Year { get; set; }
}

Upvotes: 1

Views: 137

Answers (1)

TheGeneral
TheGeneral

Reputation: 81473

Truth be told, not everything needs to be Linq. Sometimes it just makes code less maintainable and readable.

However this is potentially what a Linq solution would look like using ToDictionary

Creates a Dictionary<TKey,TValue> from an IEnumerable<T>.

private Dictionary<string, decimal> GetRateByYear(IEnumerable<EmployerCu> cuList, HashSet<long> activeCuSet, int year)
  => cuList.Where(x => activeCuSet.Contains(x.PayrollClassId))
                .ToDictionary(
                    x => x.Code,
                    x => x.Rates.LastOrDefault(y => y.Year == year)?.Value / Percentile ?? 0);

Note : i used LastOrDefault as that was what your loop was doing

Upvotes: 1

Related Questions