Reputation: 1730
There is list of int variable
data = List<int>
It contains few ints above the 0, few int's under 0 and so on. Data looks like:
-2962
-5787
-1671
-5667
-498
-4463
1399
3608
2173
I need to find the first item, when this function crosses the 0 from + to - (or from - to +) to get only first items above 0 or first items under 0 (depends on the sign of first item if it + or -).
So my code is:
var itemSign = 0;
foreach (var item in data)
{
if (itemSign == Sign(item))
{
result.Add(item);
Console.WriteLine(item);
}
itemSign = Sign(item);
}
But output is:
-2962
-5787
-1671
-5667
-498
-4463
1399
3608
2173
It seems like it doesn't work at all because I need to get these ints in these case:
-2962
-5787
-1671
-5667
-498
-4463
How do I define that value crosses 0 in C#?
Upvotes: 2
Views: 161
Reputation: 29254
There are two versions I can think of. Both use the List<int>.FindIndex()
method.
class Program
{
static void Main(string[] args)
{
var list = new List<int>() {
-2962 ,
-5787 ,
-1671 ,
-5667 ,
-498 ,
-4463 ,
1399 ,
3608 ,
2173 ,
};
int index = list.FindIndex((x) => x>0)-1;
// index = 5
index=list.Zip(list.Skip(1), (x, y) => Math.Sign(x*y)).ToList().FindIndex((s) => s==-1);
// index = 5
}
}
The first one returns the index of the first non-negative number.
The second one multiplies consecutive numbers and if their product has a negative sign it means the numbers just changed sign.
Upvotes: 1
Reputation: 9519
Usint System.Linq
(just for fun)
var input = new List<int> { -2962, -5787, -1671, -5667, -498, -4463, 1399, 3608, 2173 };
var cross = input
.Zip(input.Skip(1), (a, b) => new []{a,b})
.TakeWhile(t => (t.First() ^ t.Last()) >> 31 == 0)
.SelectMany(_ => _)
.Distinct();
Console.WriteLine(string.Join(",", cross)); //-2962,-5787,-1671,-5667,-498,-4463
If you want just the last element in the row, or first, then Aggregate
could work:
var cross = input.Aggregate((a,b) => (a ^ b) >> 31 == 0 ? a : b); //1399
var cross = input.Aggregate((a,b) => (a ^ b) >> 31 == 0 ? b : a); //-4463
Upvotes: 0
Reputation: 1335
You can use break as soon as sign change appears :
var itemSign = Sign(data.FirstOrDefault());
var result = new List<int>();
foreach (var item in data)
{
if (itemSign == Sign(item))
{
result.Add(item);
Console.WriteLine(item);
}
else
break;
}
Upvotes: 3
Reputation: 1712
for each element in list, if >0 add to positive list, if <0 add to negative list. this is simple if else stuff....
Upvotes: -3