HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Cycling between element above and below current array element

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
arraycyclingabovebetweenelementbelowcurrentand

Problem

The title sucks, but it's really very simple - given an array and a starting element, cycle between one element above, below, then two element above, and below the starting element. For example:

Start: 5
5 > 6 > 4 > 7 > 3 > 8 > 2 ...


It doesn't matter if the code initially start with the element above or below. To complicate things a little, when you reach the end or beginning of the array, the code should continue to pick valid array elements, instead of going into invalid positions:

Start: 2
2 > 3 > 1 > 4 > 0 > 5 > 6 > 7 ...


This is the code I have. It works, but I don't really like the way to fulfil the second condition above, having that two lines repeated twice.

var distance = 0;

while ((currentHeight + this.heights[index]) = 0 ? -1 : 1);
    index += distance;

    if (index = this.heights.length) {
        distance = -distance + (distance >= 0 ? -1 : 1);
        index += distance;
    }
}


distance is the distance from the starting point, index holds the current position. The code cycles with these two lines:

distance = -distance + (distance >= 0 ? -1 : 1);
index += distance;


and it resolves the invalid array position problem by simply rerunning those two lines if it finds an invalid array position.

Solution

First off, your code was a bit difficult to read, because you combined the algorithm you need with your functionality, that you didn't explain. It's not only easier for people helping you, but also yourself, if you try to separate your problem from the application.

Your attempt was to calculate an index from the previous index. I instead created a function, that mapped a increasing index (0, 1, 2, 3, 4,...) to the targets (0, 1, -1, 2, -2,...). So we are looking for a function f(i) where f(0) = 0, f(1) = 1, f(2) = -1, f(3) = 2, etc.

I came up with: (i % 2 ? 1 : -1) * Math.floor( (i+1) / 2 ).

Now you just need a condition to skip new indexes outside your array. I came up with the following:

var yourArray = new Array(10);
var start = 2;

var i = 0;
var max = yourArray.length;

while (max) {
  var newI = (i%2?1:-1) * Math.floor((i+1)/2) + start;
  if (newI >= 0 && newI ");
    // do something with yourArray[newI];
    max--;
  }
  i++;
}


My problem was how to decide when to stop the loop. For now i just loop over twice the length of the array. That will usually lead to some unnecessary iterations, but maybe someone can come up with a better solution, or there maybe a condition that comes from your application. UPDATE: Found a solution.

Code Snippets

var yourArray = new Array(10);
var start = 2;

var i = 0;
var max = yourArray.length;

while (max) {
  var newI = (i%2?1:-1) * Math.floor((i+1)/2) + start;
  if (newI >= 0 && newI < yourArray.length) {
    document.write( newI + "<br>");
    // do something with yourArray[newI];
    max--;
  }
  i++;
}

Context

StackExchange Code Review Q#1264, answer score: 5

Revisions (0)

No revisions yet.