Felix C
Felix C

Reputation: 1775

List: Detecting switches from less than zero to greater than zero

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

Answers (2)

Eamon Nerbonne
Eamon Nerbonne

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

Jon Skeet
Jon Skeet

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

Related Questions