If I had an array of integers like
+--------------------------------------------+
| 1| 0| 1| 2| 0| 1| 0| 1| 0|-1| 0| 2| 0|-2| 0| > VALUES
+--------------------------------------------+
| 0| 1| 2| 3| 4| 5| 6| 7| 8| 9|10|11|12|13|14| > INDEX
+--------------------------------------------+
I am looking for 0 which occurs 7 times in the array above.
But I need to find indexes of 0s in the array like so:
- I can find 0's that occur only after a slot with a Abs(value)> 1 (rising of falling)
- I can find 0's that occur only after a slot with a value> 1 (rising)
- I can find 0's that occur only after slot with a negative Abs(value)
1 (falling)
So, looking at array above my logic should show indexes
- 1, 4, 12, 14 - 1st and REST (rising or falling)
- 1, 4, 12 - 1st and RISING
- 1, 14 - 1st and FALLING
The indexes above are valid since the previous value was (Abs(previous)> 1). On the other hand, 0's at index 6, 8, and 10 are of no interest since the previous array value was either 1 or -1 (so Abs(previous) <= 1)
My code below works but I feel there could be a simpler more elegant solution to this
public static void Main(string[] args)
{
int[] array = new int[15] { 1, 0, 1, 2, 0, 1, 0, 1, 0, -1, 0, 2, 0, -2, 0 };
bool found1 = true;
for (int i = 0; i < array.Length; i++)
{
if (array[i] == 0)
{
if (found1)
{
Console.WriteLine(i); //print 1st index of 0
found1 = false;
}
else
{
if (Math.Abs(array[i - 1] - array[i]) > 1)
{
Console.WriteLine("All: " + i); // print every other that fits
//1, 4, 12, 14
}
}
}
}
found1 = true;
for (int i = 0; i < array.Length; i++)
{
if (array[i] == 0)
{
if (found1)
{
Console.WriteLine(i); //print 1st index of 0
found1 = false;
}
else
{
if (Math.Abs(array[i - 1] - array[i]) > 1
&& (array[i - 1] - array[i]) > 1)
{
Console.WriteLine("Up: " + i); // print rising
//1, 4, 12
}
}
}
}
found1 = true;
for (int i = 0; i < array.Length; i++)
{
if (array[i] == 0)
{
if (found1)
{
Console.WriteLine(i); //print 1st index of 0
found1 = false;
}
else
{
if (Math.Abs(array[i - 1] - array[i]) > 1
&& (array[i - 1] - array[i]) < 1)
{
Console.WriteLine("Down: " + i); // print falling
//1, 14
}
}
}
}
Console.ReadLine();
}
2 Answers 2
You are unnecessarily looping through the array 3 times (only one loop is required). Its not clear how you will be using the results, but assuming you need to store them, then the code can be simplified to
int[] array = new int[15] { 1, 0, 1, 2, 0, 1, 0, 1, 0, -1, 0, 2, 0, -2, 0 };
// Define 3 lists from the results
List<int> all = new List<int>();
List<int> up = new List<int>();
List<int> down = new List<int>();
// Get the index of the first zero value and add to the lists
int first = Array.IndexOf(array, 0);
all.Add(first);
up.Add(first);
down.Add(first);
// Loop the remaining items in the array and add to the appropriate lists
for (int i = first + 1; i < array.Length; i++)
{
int current = array[i];
int previous = array[i - 1];
if (current != 0)
{
continue;
}
if (Math.Abs(previous - current) > 1)
{
all.Add(i);
if (previous - current > 1)
{
up.Add(i);
}
else if (previous - current < 1)
{
down.Add(i);
}
}
}
The result is
all
contains [1, 4, 12, 14]
, up
contains [1, 4, 12]
and down
contains [1, 14]
A lot of extra code in my opinion
You don't need 3 loops
You don't test the first
If the value is zero there is not purpose to subtracting it
public static void Zero()
{
int[] array = new int[15] { 1, 0, 1, 2, 0, 1, 0, 1, 0, -1, 0, 2, 0, -2, 0 };
List<int> all = new List<int>();
List<int> up = new List<int>();
List<int> down = new List<int>();
int previous = array[0];
int current;
for (int i = 1; i < array.Length; i++)
{
current = array[i];
if (current == 0)
{
if (previous < -1)
{
all.Add(i);
down.Add(i);
}
else if (previous > 1)
{
all.Add(i);
up.Add(i);
}
}
previous = current;
}
Debug.WriteLine("done");
}
int firstIndex = Array.IndexOf(array, 0);
to give the first index of0
. And you could reduce this down to just one loop (storing the results in 3 separateList<int>
variables based on if/else conditions) \$\endgroup\$