Let's take a class called Cls
:
public class Cls
{
public int SequenceNumber { get; set; }
public int Value { get; set; }
}
Now, let's populate some collection with following elements:
Sequence Number Value ======== ===== 1 9 2 9 3 15 4 15 5 15 6 30 7 9
What I need to do, is to enumerate over Sequence Numbers and check if the next element has the same value. If yes, values are aggregated and so, desired output is as following:
Sequence Sequence Number Number From To Value ======== ======== ===== 1 2 9 3 5 15 6 6 30 7 7 9
How can I perform this operation using LINQ query?
MoreLinq provides this functionality out of the box
It's called
GroupAdjacent
and is implemented as extension method onIEnumerable
:There is even a Nuget "source" package that contains only that method, if you don't want to pull in an additional binary Nuget package.
The method returns an
IEnumerable<IGrouping<TKey, TValue>>
, so its output can be processed in the same way output fromGroupBy
would be.Here is an implementation without any helper methods:
The idea is:
You can use this linq query
Demo
You can do it like this:
The idea is to use
Aggregate
creatively: starting with a list consisting of a singleRun
, examine the content of the list we've got so far at each stage of aggregation (theif
statement in the lambda). Depending on the last value, either continue the old run, or start a new one.Here is a demo on ideone.
Untested dark magic follows. The imperative version seems like it would be easier in this case.
I was able to accomplish it by creating a custom extension method.
Here's the implementation:
And the expected output: