Home > Net >  Percent change of a IList<T> returning IList<T> using LINQ
Percent change of a IList<T> returning IList<T> using LINQ

Time:04-06

Given a List<T> where T is float/decimal/double, using LINQ, compute the percent change of all the values.

This is the definition of PercentChange (without error checking for example if a is zero)

static double PercentChange(double a, double b)
{
    double result = 0;
    result = (b - a) / a;
 
    return result;
}

var list = new List<double>();
list.Add(2.0);
list.Add(2.5);
list.Add(2.0);
list.Add(1.75);

Then using LINQ would return a new List one element less, with values:

[.25, -.20, -.125] 

I know I can loop. I would like a functional version using LINQ.

CodePudding user response:

I'm not sure I'd find this approach more readable than a loop, but the LINQ approach would be:

list.Zip(list.Skip(1), PercentChange)

Outputs:

[.25, -.2, -.125]

The idea is to take the first list, "zip" it with itself, but skip the first element (so y is the next element) and apply your PercentChange function on it. Zip will automatically truncate the resulting sequence to the size of the smaller sequence, so you end up with three elements.

CodePudding user response:

Several solutions are available, I prefer the following one, combining LINQs Enumerable.Zip with LINQS Enumerable.Skip

var result = list.Zip(list.Skip(1), (a, b) => (b - a) / a);
Console.WriteLine(string.Join(", ", result));

which prints

0.25, -0.2, -0.125

This very compact solution allows calculation of your list like visualized here:

a:    2.0        2.5        2.0       1.75
b:    2.5        1.0        1.75
res:  0.25      -0.2       -0.125
  • Related