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

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

The length of my array is always an odd number.

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 need to start from the center of this matrix (ie myArray[Math.floor(myArray.length / 2)] )

In my example: 24

Then I have to alternate the left and right numbers until I go through the entire line.

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

After the line is completed, I alternate between the upper and lower digits, I repeat the left / right logic for this line.

In my example, to enter myArray as an input value, I have to 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 in what has been achieved?

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

+8
javascript arrays
source share
8 answers

I think I have this:

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)])); } } 
+1
source share

I recommend investing 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 with this, you can either manually translate it back into the equivalent ES5 design, or just let the transporter do the job for you: Demo .

+3
source share

Another option:

 // Define number of elements var n = 49; // Calculate center var start = Math.floor(n / 2); // Calculate solution var result = [get_row(start, n)]; for (var l = 1; l < Math.sqrt(n) / 2; l++) { result.push(get_row(start - l, n)); result.push(get_row(start + l, n)); } // Print solution for (var k = 0; k < result.length; k++) { console.log(result[k]); } /////////////////////////////////////////////// function get_row(c, size) { var a = []; a.push(c); for (var i = 1; i < Math.sqrt(size) / 2; i++) { a.push(c - i * Math.sqrt(size)); a.push(c + i * Math.sqrt(size)); } return a; } 
+1
source share

Here's another approach using nested loops, the only resulting array.

JSfiddle Demo

 var num = 7, middleElement = Math.floor(num * num / 2); // Square number and get the center number var result = []; // To store resulting array for(var j = 1; j <= num; j++) { // This will be the middle element, ie 24, 23, 25, 22, 26, 21, 27 // Will be calculated dynamically element = j % 2 ? middleElement + Math.floor(j / 2) : middleElement - Math.floor(j / 2); result.push(element); // Add middle element in the resulting array for(var i = 1; i < num; i++) { // For next six elements // Get the number from current number element = i % 2 ? element - num * i : element + num * i; result.push(element); } } 

 var num = 7, middleElement = Math.floor(num * num / 2); // Square number and get the center number var result = []; // To store resulting array for(var j = 1; j <= num; j++) { // This will be the middle element, ie 24, 23, 25, 22, 26, 21, 27 // Will be calculated dynamically element = j % 2 ? middleElement + Math.floor(j / 2) : middleElement - Math.floor(j / 2); result.push(element); // Add middle element in the resulting array for(var i = 1; i < num; i++) { // For next six elements // Get the number from current number element = i % 2 ? element - num * i : element + num * i; result.push(element); } } console.log(result); 
+1
source share

Another approach, with an array for position numbers:

 var array = [], // 3 2 4 1 5 0 6 length = 7, lower = 0, upper = length - 1, result; while (lower < upper) { // generate array array.unshift(upper--); array.unshift(lower++); } lower === upper && array.unshift(upper); result = Array.apply(null, { length: length }).map(function (_, j) { return Array.apply(null, { length: length }).map(function (_, i) { return array[i] * length + array[j]; }); }); document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>'); 
+1
source share

The number that follows the one you are processing (say 24 ) is always subtracting your number ( 24 ) by a multiple of the length of the matrix (in your example, this length is 7).

Let subject be the number you are processing and hop length of the matrix.

So, iteration by row, two per iteration, always filling two cells at a time, the first with subject - hop * <counter of iteration> , and the second cell with subject + hop * <counter of iteration>

0
source share

I hope I understand your algorithm, but this should work:

If the length is always an odd square, then your index minima are 0, and the maxima are Sqrt (n + 1) -1.

 var verticalup=false; var horizontalforward=false; var initial=myArray[Math.floor(myArray.length / 2)]; var maximum=Math.sqrt(myArray.length+1); var current={vertical:initial,horizontal:initial}; var continue=true; while (continue) { //do something here with the current selection if (current.horizontal===0) { verticalup=!verticalup; current.vertical+=(verticalup?1:-1); } horizontalforward=!horizontalforward; current.horizontal+=(horizontalforward?1:-1); continue=current.vertical>=0 && current.vertical<maxima && current.horizontal>=0 && current.horizontal<maximum; } 
0
source share

I think something in the lines ...

 var center = Math.floor(myArray.length / 2; var parity = function(p){ return (p%2)*2-1; //if the number is even, returns -1 otherwise 1 } //adds to cetner location half on index, signed with its parity, so we get an alternating effect each time index grows bigger //for 0,1,2,3,4,5,6... will return 0,1,-1,2,-2,3,-3... var step = function(index){ return (Math.floor((index+1)/2))*parity(index); } for (var i=0;i<size;i++){ for (var j=0;j<size;j++){ a[center-step(i)][center-step(j)]; } } 

It mainly uses the parity i and j to determine whether to go up or down, and also to the left or right of the central (central, central) point.

0
source share

All Articles