Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to do this "weird" loop through my array?

I need to loop through a simple array in a "weird" way.

The length of my array is always a odd squared number.

Let's say the length is 49. To make it clearer, my elements are the index of the array. So I have something like:

myArray = [0, 1, 2, 3, 4 ... 47, 48]

So, you can imagine the following square matrix:

0   7   14  21  28  35  42
1   8   15  22  29  36  43
2   9   16  23  30  37  44
3   10  17  24  31  38  45
4   11  18  25  32  39  46
5   12  19  26  33  40  47
6   13  20  27  34  41  48

I have to start with the center of this matrix (i.e. myArray[Math.floor(myArray.length / 2)])

In my example: 24

Then I have to alternate between left and right numbers until I pass through all the row.

In my example, for the first iteration : 17, 31, 10, 38, 3, 45

Once a row is done, I alternate between up then bottom numbers an reiterate the left/right logic for the given row.

In my example, for myArray as input I should loop in the following order:

24, 17, 31, 10, 38, 3, 45, 
23, 16, 30, 9, 37, 2, 44,
25, 18, 32, 11, 39, 4, 46,
22, 15, 29, 8, 36, 1, 43,
26, 19, 33, 12, 40, 5, 47,
21, 14, 28, 7, 35, 42, 0,
27, 20, 34, 13, 41, 6, 48

Could you help me the achieved it properly?

Here is what I did so far: https://jsfiddle.net/6qzkk2zx/

like image 381
Alex Avatar asked Feb 04 '16 14:02

Alex


2 Answers

I think I have it:

https://jsfiddle.net/2dbj68t3/2/

var start = (array.length - 1) / 2;
var square = Math.sqrt(array.length);
newArray.push(array[start]);
for (j = 1; j <= Math.floor((square / 2)); j++) {
    newArray.push((array[start - (j * square)]));
    newArray.push((array[start + (j * square)]));
}
for (i = 1; i <= Math.floor((square / 2)); i++) {
    newArray.push((array[start - i]));
    for (j = 1; j <= Math.floor((square / 2)); j++) {
        newArray.push((array[start - i - (j * square)]));
        newArray.push((array[start - i + (j * square)]));
    }
    newArray.push((array[start + i]));
    for (j = 1; j <= Math.floor((square / 2)); j++) {
        newArray.push((array[start + i - (j * square)]));
        newArray.push((array[start + i + (j * square)]));
    }
}
like image 31
nachosn89 Avatar answered Oct 12 '22 15:10

nachosn89


I recommend nesting two ES6 generators:

for (let y of outwards(7)) {
    for (let x of outwards(7)) {
        var i = y*7+x;
        use(arr[i]); // for one-dimensional array
        use(arr[x][y]) // for two-dimensional array
    }
}

function* outwards(n) {
    console.assert(n%2 == 1);
    var x = (n-1)/2; // starting in the middle
    yield x;
    for (var i=1; i<n;) {
        x -= i++; // jumping to the left
        yield x;
        x += i++; // and right
        yield x;
    }
}

Starting from that, you could either manually translate it back to an equivalent ES5 construct, or just let a transpiler do the work for you: Demo.

like image 50
Bergi Avatar answered Oct 12 '22 15:10

Bergi