Array of the process from the middle

I need to go through an array of middle words.

var array = [a,b,c,d,e]; 

I need to print in the following order: c, d, b, d, and

I already split the array in half, first moving forward and then stepping back, which is already an improvement, but I really need to go one on each side to the end of the array on each side.

Say I want to start in the middle. I have the following before the loop operator, condition, and I can’t understand which third part needs to be changed on each side in stages.

 for (var i = Math.floor(array.length/2); i >= 0 || i < array.length; i?){ //Do Something here. } 

Does anyone know how to do this? Obviously, I cannot verify this in this state.

thanks

I modified the answer below (Thank you very much) to come up with this feature. It allows you to start from anywhere in the array and choose the direction for the transition. I am sure that it could be written more elegantly. There is also security for invalid index numbers.

 var array = ["a", "b", "c", "d", "e"]; function processArrayMiddleOut(array, startIndex, direction){ if (startIndex < 0){ startIndex = 0; } else if ( startIndex > array.length){ startIndex = array.lenght-1; }; var newArray = []; var i = startIndex; if (direction === 'right'){ var j = i +1; while (j < array.length || i >= 0 ){ if (i >= 0) newArray.push(array[i]); if (j < array.length) newArray.push(array[j]); i--; j++; }; } else if(direction === 'left'){ var j = i - 1; while (j >= 0 || i < array.length ){ if (i < array.length) newArray.push(array[i]); if (j >= 0) newArray.push(array[j]); i++; j--; }; }; return newArray; } var result = processArrayMiddleOut(array, 2, 'left'); alert(result.toString()); 

http://jsfiddle.net/amigoni/cqCuZ/

+4
source share
6 answers

Two counters, one goes up, the other goes down:

 var array = ["a", "b", "c", "d", "e"]; var newArray = []; var i = Math.ceil(array.length/2); var j = i - 1; while (j >= 0) { newArray.push(array[j--]); if (i < array.length) newArray.push(array[i++]); } 

http://jsfiddle.net/X9cQL/

+8
source

Therefore, I decided to review this without feeling very satisfied with the first answer I gave. I was sure that there would be some relationship between the index numbers when the data was successfully reordered; I found this pattern when adding an iteration number to the last position position.

For our initial array, we will use the following: ['a', 'b', 'c', 'd', 'e'] .

Our starting point is Math.floor( arr.length / 2 ) , which gives us 2 corresponding to c in the array values. This is at iteration 0 . The following instructions detail how we go through an array with an odd number of values:

  Position | Direction | Iteration | New Position | Value at Position ----------+-----------+-----------+--------------+------------------- 2 | - | 0 | 2 | c 2 | + | 1 | 3 | d 3 | - | 2 | 1 | b 1 | + | 3 | 4 | e 4 | - | 4 | 0 | a 

You will see the template when our iteration is odd, we will add it to our location to find a new position. When the iteration is negative, we subtract it from our position to find a new location.

When working with an array with an even number of values, the rules are inverted. When you have an even number of values, we subtract the odd iterations from the location to get a new position, and even add iterations to our location to find the next value.

To demonstrate how little code is required to execute this sorting logic, the following is a miniature version of the above logic (the above link is more readable):

 // DON'T USE THIS IN PRODUCTION, OR YOUR TEAM MAY KILL YOU function gut(a){ var o=[],s=a.length,l=Math.floor(s/2),c; for(c=0;c<s;c++)o.push(a[l+=(s%2?c%2?+c:-c:c%2?-c:+c)]); return o } 

Implementing the above logic in a more readable way:

 // Sort array from inside-out [a,b,c,d,e] -> [c,d,b,e,a] function gut( arr ) { // Resulting array, Counting variable, Number of items, initial Location var out = [], cnt, num = arr.length, loc = Math.floor( num / 2 ); // Cycle through as many times as the array is long for ( cnt = 0; cnt < num; cnt++ ) // Protecting our cnt variable (function(){ // If our array has an odd number of entries if ( num % 2 ) { // If on an odd iteration if ( cnt % 2 ) { // Move location forward loc = loc + (+cnt); } else { // Move location backwards loc = loc + (-cnt); } // Our array has an even number of entries } else { // If on an odd iteration if ( cnt % 2 ) { // Move location backwards loc = loc + (-cnt); } else { // Move location forwards loc = loc + (+cnt); } } // Push val at location to new array out.push( arr[ loc ] ); })() // Return new array return out; } 
+2
source

Ok, solve this problem step by step:

  • An array can have an odd or even number of elements:
  • If the array has an odd number of elements:
    • The middle element is in the index (array.length - 1) / 2 . Let this index be called mid .
    • There are a number of mid elements to the left of the middle element. Obviously.
    • There is a mid number of elements to the right of the middle element.
  • If the array has an even number of elements:
    • The middle element is at index array.length / 2 . Let this index be called mid .
    • There are a number of mid elements to the left of the middle element. Obviously.
    • There is a mid - 1 number of elements to the right of the middle element.

Now let's create a function to solve this problem using the above data:

 function processMidOut(array, callback) { var length = array.length; var odd = length % 2; // odd is 0 for an even number, 1 for odd var mid = (length - odd) / 2; // succinct, isn't it? callback(array[mid]); // process the middle element first for (var i = 1; i <= mid; i++) { // process mid number of elements if (odd || i < mid) // process one less element if even callback(array[mid + i]); // process the right side element first callback(array[mid - i]); // process the left side element next } } 

That is all there is. Now let me create some arrays and process them in the middle:

 var odd = ["a", "b", "c", "d", "e"]; var even = ["a", "b", "c", "d", "e", "f"]; var oddOrder = ""; var evenOrder = ""; processMidOut(odd, function (element) { oddOrder += element; }); processMidOut(even, function (element) { evenOrder += element; }); alert(oddOrder); alert(evenOrder); 

Here you can find a working demo: http://jsfiddle.net/xy267/1/

+1
source

Very interesting algorithm. Here is what I came with:

 walkMidleOut = function(arr, callback) { var mid = (arr.length - arr.length % 2) / 2; for (var i = 0; i < arr.length; i++) { var s = -1, j = (i % 2 ? (s = 1, i + 1) : i) / 2, index = mid + s * j == arr.length ? 0 : mid + s * j; callback.call(arr, arr[index], index); } } 

Using:

 walkMidleOut([1,2,3,4,5], function(el, index) { console.log(el, index); }); 

You'll get:

 3 2 4 3 2 1 5 4 1 0 

The function can be used with any number of elements, odd or even.

+1
source

What about using concat() and slice() ? You can simply pass this index of the middle element.

 Array.prototype.eachFrom = function(index){ var index = index > this.length ? 0 : index; return [].concat(this.slice(index), this.slice(0, index)); } 

for example:

 var arr = ['a', 'b', 'c', 'd', 'e'], arr = arr.eachFrom(2); for( var i = 0; i < arr.length; i++ ) { doFunThings(); } 
+1
source

Using underscore and _ (Object) .Sort_Inside_Out ():

 _.mixin( { Sort_Inside_Out: function ( Object ) { Counter = 0 return ( _( Object ).sortBy( function ( Element ) { Counter = -Counter + ( ( Math.sign( Counter ) == 1 ) ? 0 : 1 ) return ( Counter ) } ) ) }, } ) 
0
source

Source: https://habr.com/ru/post/1440332/


All Articles