Reputation: 1775
is there any existing linq function or similiar functions to detect how often values in an ordered list changes from less than zero to greater than zero?
As example, values:
5
2
-2
-5
8 <--- First
6
2
0
1
-3
-5
-3
2 <--- Second
Total count: 2
Upvotes: 0
Views: 180
Reputation: 48096
You can implement this in one pass using Aggregate
:
seq.Aggregate(new { Count=0, LastN = 0}, (state, n) => new {
Count = state.Count + (n > 0 && state.LastN < 0 ? 1 : 0),
LastN = n == 0 ? state.LastN : n
}).Count
This takes into account your wish to include "gradual" transitions such as -1,0,1.
However, a foreach may be easier, simply because it's more conventional. It'll also be faster:
var count = 0;
var lastN = 0;
foreach(var n in seq) {
if(n > 0 && lastN < 0)
count++;
if (n != 0)
lastN = n;
}
Upvotes: 1
Reputation: 1502066
Sure - it's certainly easy if you're using .NET 4 or higher, using Zip
:
// TODO: Consider how you want to handle 0 itself
var count = list.Zip(list.Skip(1), (x, y) => new { x, y })
.Count(pair => pair.x > 0 && pair.y < 0);
That shouldn't be hard to convert into VB if you know VB well :)
Alternatively, if you've really got a list, you can just do it "manually" pretty easily without LINQ:
int count = 0;
for (int i = 0; i < list.Count - 1; i++)
{
if (list[i] > 0 && list[i + 1] < 0)
{
count++;
}
}
Upvotes: 3