Count number of Exceedence in a series
I have a series data in IEnumrable&l开发者_开发百科t;double>
.
Let the dummy data be:
0
0
0
1
1.6
2.5
3.5
2.51
1.0
0
0
0
2.52
3.5
6.5
4.5
1.2
1.0
2.53
3.5
let my value of Exceedence be 1.5, so I want to count the number of time my value in series goes above 1.5 (basically number of times 1.5 constant line cut the graph). In above case it will be 3 ({1.6-2.51}, {2.52-4.5}, {2.53-3.5}).
I can do this by iterating through each member and keeping the count everytime it goes up or down the Exceedence value.
I am wondering is there any way to do this using LINQ query.
Is that what you want?
bool isAbove = false;
int count = yourList.Count(x =>
{
if (x > 1.5 && !isAbove)
{
isAbove = true;
return true;
}
else if (x < 1.5)
{
isAbove = false;
}
return false;
});
You could use this helper function that will give you all of the ranges above your limit
public IEnumerable<IEnumerable<double>> GetRangesAboveLimit(IEnumerable<double> source, double limit)
{
//keep going until we've processed the entire range
while (source.Any())
{
//skip elements below the limit
source = source.SkipWhile(e => e <= limit);
//yield the elements above the limit
yield return source.TakeWhile(e => e > limit);
//now skip those elements and then continue
source = source.SkipWhile(e => e > limit);
}
}
You'd then be able to use it like this:
var range = new double [] { /* initialise here */ };
var rangesAboveLimit = GetRangesAboveLimit(range, 1.5);
This would then allow you to not only get the count of how many ranges are above your limit (3) but also allow you to look at the values of those ranges.
The results for your specific example look like this:
This is probably not the best way of doing it, but it's a sneaky way of doing it with LINQ.
float[] numbers = { 0f, 0f, 0f, 1f, 1.6f, 2.5f, 3.5f, 2.51f, 1.0f, 0f, 0f, 0f, 2.52f, 3.5f, 6.5f, 4.5f, 1.2f, 1.0f, 2.53f, 3.5f };
int count = numbers.Where((n, i) => i > 0 && n > 1.5f && numbers[i - 1] < 1.5f).Count();
Just for fun - the same result, using Jon Skeet "SelectPairs" extension method (link):
yourList.SelectPairs((x,y) => (x < 1.5 && y > 1.5) ? 1 : 0).Sum()
But this doesn't work if there is only one value in the list.
P.S. DoctaJonez answer FTW! :)
精彩评论