# Simplify LINQ to Create Step Values

Assume the following definition:

public class DataPoint {
public DateTime Date { get; private set; }
public double Value { get; private set; }
public DataPoint(DateTime date, double value) { Date = date; Value = value; }
}


If var points = ... //a date ordered list of DataPoints

I want to convert points into a list or array that represents the steps between each subsequent value. E.g. [3, 5, 6, 10.5] would go to [3, 2, 1, 4.5] with dates.

Here's what I have:

var steps = (new[] {points.First()})
.Concat(points
.Skip(1)
.Zip(points,
(curr, prev) => new DataPoint(curr.Date, curr.Value - prev.Value)))


I think my ruby background might have gotten the best of me as that doesn't seem very readable. Any thoughts on how to make things more approachable?

• I would use a foreach loop + a local var – miniBill Jun 13 '14 at 22:30

In my opinion, the Concat part is what's throwing it off. There is a lesser utilized Select overload that provides access to the index, which could be used like so (ignoring the DataPoint part to make a minimal example):

double[] points = new double[] { 3, 5, 6, 10.5 };

points.Select ((p, i) => p - (i == 0 ? 0 : points[i - 1]));

• Phenomenal, the Select overload is nice but the gravy was really in the ternary usage. Thanks! – TCopple Jun 13 '14 at 17:20

You might want to consider doing your pairing first, which could then be extracted into an extension method. Not sure about terminology here.

public static class EnumerableExtension
{
public static IEnumerable<Tuple<T, T>> Pairwise<T>(
this IEnumerable<T> enumerable,
{
new T[] { leadingItem }.Concat(enumerable).Zip(enumerable, Tuple.Create);
}
}


And then your code would look something like this

var points = GetAllTheDataPoints();
.Select(t => new DataPoint(t.Item2.Date, t.Item2.Value - t.Item1.Value));


Where Datapoint.Zero is just a DataPoint with value 0. If you want to make things even more explicit you could introduce your own Pair<T, T> type rather than using Tuple<T, T> since the property names Item1 and Item2 are kinda meh.

• Something like this would be preferred over my answer if it would get a lot of reuse in a codebase. Used in one place, I think more people would directly understand something using framework linq methods if it was concise enough. Jon Skeet actually has a PairWise extension method in his MoreLinq library that makes use of Func types instead of Tuple for easier lambda expressions: code.google.com/p/morelinq/source/browse/MoreLinq/… – Ocelot20 Jun 13 '14 at 19:11

This is my proposed solution:

private static IEnumerable<double> Deltas(IEnumerable<double> sequence)
{
var prev = 0.0;
foreach (var item in sequence)
{
yield return item - prev;
prev = item;
}
}


The advantage of this version over @Ocelot20's is that it doesn't force your collection to implement IList, meaning

• it's more reusable, and
• it doesn't force you to have the sequence in memory all at once.

You want to find substraction beetwen i[0] - 0, i[1] - i[0], ... which can be solved by creating new enumeration

    int[] points1 = { 3, 5, 6, 10 }; // points[0], points[1], points[2], points[3]
int[] points0 = { 0, 3, 5, 6 };  //         0, points[0], points[1], points[2]


To create points0 I need to add int = 0 at start.

    int[] points = { 3, 5, 6, 10 };

var steps = new int[] { 0 }.Concat(points)
.Zip(points, (x1, x2) => x2 - x1);


Overall when I need to use indexes I usually stick to for loop.