Warm tip: This article is reproduced from stackoverflow.com, please click
arrays c# dictionary

Is there a way to Translate an array into a dictionary

发布于 2020-03-27 10:29:17

The problem I'm having is that I'm not sure how to translate my double array into a Dictionary. I have some LINQ Where statements that are pretty heavy, so I wanted to use the keys of my Dictionary to look up a specific value. I have two classes with getters and setters and then my calculator.

I've fiddled around a bit with trying to make either a lookup or a Dictionary, but didn't have any luck.

public class Product
{
    public int EarliestOriginYear { get; set; }
    public int NoOfDevelopmentYears { get; set; }
    public string ProductName { get; set; }
    public IEnumerable<ProductIncrementalValue> ProductIncrementalValues { get; set; }
}

public class ProductIncrementalValue
{
    public string ProductName { get; set; }
    public int OriginYear { get; set; }
    public int DevelopmentYear { get; set; }
    public double IncrementalValue { get; set; }
}

public IList<double> Calculate(Product product)
{
     IList<double> cumulativeDataTriangle = new List<double>();
     if (!product.ProductIncrementalValues.Any())
        return cumulativeDataTriangle;

     for (int i = 0; i < product.NoOfDevelopmentYears; i++)
     {
        // This is what I want to change (where statements)
        var incrementalValues = product.ProductIncrementalValues
            .Where(v => v.OriginYear == product.EarliestOriginYear + i)
            .ToList(); 

        double previous = 0;

        for (int j = 0; j < product.NoOfDevelopmentYears - i; j++)
        {
            // This is what I want to change
            double incrementalValue = incrementalValues.Where(val =>
                val.DevelopmentYear == val.OriginYear + j)
                .Select(x => x.IncrementalValue)
                .FirstOrDefault();

            var tmp = incrementalValue + previous;
            cumulativeDataTriangle.Add(tmp);
            previous = tmp;
        }
     }

     return cumulativeDataTriangle;
}
Questioner
user11251276
Viewed
65
cem 2019-07-04 00:32

You could group the products by OriginYear and DevelopmentYear before the loops. Something like this might help:

public IList<double> Calculate(Product product)
{
    IList<double> cumulativeDataTriangle = new List<double>();
    if (!product.ProductIncrementalValues.Any())
        return cumulativeDataTriangle;

    var lookup = product.ProductIncrementalValues.ToLookup(v => (v.OriginYear, v.DevelopmentYear), v => v.IncrementalValue); 
    for (int i = 0; i < product.NoOfDevelopmentYears; i++)
    {
        var originYear = product.EarliestOriginYear + i;
        double previous = 0;
        for (int j = 0; j < product.NoOfDevelopmentYears - i; j++)
        {
            var developmentYear = originYear + j;
            var incrementalValues = lookup[(originYear, developmentYear)];
            double incrementalValue = incrementalValues.FirstOrDefault();

            var tmp = incrementalValue + previous;
            cumulativeDataTriangle.Add(tmp);
            previous = tmp;
        }
    }

    return cumulativeDataTriangle;
}