Tengo esta matriz:

var array = [0,1,2,3,4,5,6,7,8,9,10];

Para realizar un bucle en sentido horario (Inicio 8, luego 9, luego 10, luego 0 .....) Estoy haciendo esto:

var start = 8;
for(i = 0; i < array.length; i++){
    index = (start+i)%array.length;
    ....
}

1) A la dirección de las agujas del reloj, ¿hay una mejor manera?

2) Para realizar un bucle en sentido contrario a las agujas del reloj (Inicio 2, luego 1, luego 0, luego 10 ...), ¿qué debo hacer?

1
Eduardo Arruda Pimentel 7 may. 2016 a las 23:50

5 respuestas

La mejor respuesta

Para hacerlo de manera similar a lo que hizo, disminuya el índice del índice inicial y agregue la longitud antes de recortar:

var start = 8;
for(i = 0; i < array.length; i++) {
  index = (start - i + array.length) % array.length;
  // ....
}

Con respecto a "cómo hacerlo mejor", crearía una función auxiliar simple:

function getIndexInRange(index, length) {
  var trim = index % length;
  var nonNegative = trim + length;
  return nonNegative % length;
}

Entonces todo se vuelve más claro:

var start = 8;
for(i = 0; i < array.length; i++) {
  var index = getIndexInRange(start + i, array.length);
  // ....
}

for(i = 0; i < array.length; i++) {
  var index = getIndexInRange(start - i, array.length);
  // ....
}

Ahora incluso puede iterar la matriz varias veces si lo desea, y aún funciona:

for(i = 0; i < array.length * 5; i++) {
  var index = getIndexInRange(start - i, array.length);
  // ....
}
2
Amit 7 may. 2016 a las 21:12

Puede usar Array.prototype.slice para cambiar el inicio de la matriz:

Array.prototype.enhancedForEach = function(callback, start = 0, clockwise = true) {
  var array = this;
  start %= array.length;

  array.slice(start)
    .concat(array.slice(0, start))
    .forEach((v, i, arr) => {
      var index = clockwise ? i : arr.length - i - 1;
      callback(arr[index], index, arr);
    });

}

array = Array.from({
  length: 20
}, (v, i) => i);

array.enhancedForEach(v => console.log(v), 4);

array.enhancedForEach(v => console.log(v), 0, false);
http://stackoverflow.com/posts/37981887/edit#
1
Morteza Tourani 23 jun. 2016 a las 03:35
var array = [0,1,2,3,4,5,6,7,8,9,10];


function clockwise(start){
    for (var i = 0; i < array.length; i++){
        console.log((start+i)%array.length);
    }
}

function counterClockwise(start){
    for (var i = array.length; i > 0; i--){
        console.log((start+i)%array.length);
    }
}

console.log('clockwise start from ');
clockwise(8);
console.log('clockwise End  ');

console.log('counterClockwise start from ');
counterClockwise(2);
console.log('counterClockwise End  ');
1
Kelvin 7 may. 2016 a las 21:09

Creé una jsbin aquí.

http://jsbin.com/tucusal/edit?html,js,console

Incluso puede crear una función que tome la dirección de entrada y luego atraviese la matriz en esa dirección.

var array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

var start = 8;
clockwise = 1;
anti_clockwise = -1;

direction = clockwise;
traverse(array, start, anti_clockwise);

function traverse(array, start,  direction) {
  var count = array.length;
  for (i = start; count > 0; i += direction) {
    var index = array[(array.length + i) % array.length];
    count--;
    console.log(index);
  }
}
1
Zohaib Ijaz 7 may. 2016 a las 21:32

Considere usar una sola función para ambas direcciones:

var array = [0,1,2,3,4,5,6,7,8,9,10];

function iterateByClockRotation(start, array, direction){
    var len = array.length, current = start;
    while (len--) {
        current = array.indexOf(current);
        if (current < 0) current = ((direction === "clockwise")? 0 : array.length-1);
        console.log(array[current]); // the current value
        (direction === "clockwise")? current++ : current--;
    }
}

iterateByClockRotation(8, array, "clockwise");

La salida para la dirección 'en sentido horario':

8
9
10
0
1
2
3
4
5
6
7

iterateByClockRotation(2, array, "anticlockwise");

La salida para la dirección 'en sentido antihorario':

2
1
0
10
9
8
7
6
5
4
3
1
RomanPerekhrest 7 may. 2016 a las 21:28