Iterate through array starting from the center and moving outwards

I am looking to iterate through an array starting from the middle and moving outwards.

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

The desired order of printing would be: c,d,b,e,a

I have managed to divide the array in half and traverse it both forward and backward, but I need to go one element at a time on each side until reaching the end of the array.

If I were to begin from the middle, here is what I have before the loop:

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

Can anyone provide guidance on how to achieve this functionality?

Thank you!

I adapted the answer below and created this function. It allows for starting from any position in the array and selecting the direction to move towards. Although it works, I believe there could be more elegant ways to write this code. It also includes safety measures for incorrect 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/

Answer №1

Here's some code that utilizes two counters, one counting up and the other counting down:

const animals = ["lion", "tiger", "cheetah", "leopard", "jaguar"];
const newArr = [];

let x = Math.floor(animals.length / 2);
let y = x - 1;

while (y >= 0) {
    newArr.push(animals[y--]);
    if (x < animals.length) newArr.push(animals[x++]);
}

Check out this code snippet in action!

Answer №2

Upon reflection, I felt compelled to revisit this topic as my initial answer left me unsatisfied. I was convinced that there must be a correlation between the index numbers when reordering the data; eventually, I discovered a trend in adding the iteration number to the last item position.

Let's start with an array consisting of: ['a', 'b', 'c', 'd', 'e'].

The starting point is at index Math.floor( arr.length / 2 ), resulting in 2, which corresponds to element c. This marks the beginning of our process on iteration 0. The following steps outline how we navigate through an array with an odd number of elements:

 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

A pattern emerges where odd iterations involve addition to the current position to find the new position, while negative iterations necessitate subtraction from the position to determine the new location.

In contrast, dealing with an even number of elements requires a shift in rules. For arrays with an even count, odd iterations lead to subtraction from the location for the new position, and even iterations result in addition to the location to access the next value.

To showcase the efficiency of the sorting logic, below is a minified version of the aforementioned code (note: readability is sacrificed for brevity):

// AVOID USING THIS IN PRODUCTION FOR YOUR OWN SAFETY
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
}

If you prefer a more readable implementation of the logic described above, here it is:

// 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;

}

Answer №3

Alright, let's break down this issue step by step:

  1. A given array can have either an odd or even number of elements:
  2. If the array consists of an odd number of elements:
    1. The middle element is located at index (array.length - 1) / 2. This index will be known as mid.
    2. There are mid elements to the left of the middle element.
    3. Similarly, there are mid elements to the right of the middle element.
  3. If the array contains an even number of elements:
    1. The middle element can be found at index array.length / 2, denoted as mid.
    2. There are mid elements situated to the left of the middle element.
    3. Conversely, there are mid - 1 elements present on the right side of the middle element.

Now, we need to devise a function to address this problem using the information provided above:

function handleMiddleValues(array, callback) {
    var length = array.length;
    var odd = length % 2;         
    var mid = (length - odd) / 2;

    callback(array[mid]);         

    for (var i = 1; i <= mid; i++) {  
        if (odd || i < mid)           
            callback(array[mid + i]);
        callback(array[mid - i]);     
    }
}

That covers our approach. Let's apply this function to different arrays to process them with their middle values extracted:

var oddArr = ["x", "y", "z"];
var evenArr = ["x", "y", "z", "w"];

var resultOdd = "";
var resultEven = "";

handleMiddleValues(oddArr, function (element) {
    resultOdd += element;
});

handleMiddleValues(evenArr, function (element) {
    resultEven += element;
});

alert(resultOdd);
alert(resultEven);

For a demonstration, check out this working example: http://jsfiddle.net/abc123/1/

Answer №4

Impressive algorithm! Check out my version below:

walkMiddleOut = 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);
    }
}

Example of how to use the function:

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

The output will be:

3 2
4 3
2 1
5 4
1 0

This function works with any number of elements, whether odd or even.

Answer №5

Have you thought about utilizing the concat() and slice() methods? Simply provide the index of the middle element as an argument.

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

For instance:

var array = ['x', 'y', 'z', 'w', 'v'], selectedArray = array.selectFrom(2);
for( var j = 0; j < selectedArray.length; j++ ) { performCoolTasks(); }

Answer №6

Utilizing the power of underscore library along with _( Object ).Sort_Inside_Out() method:

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

Answer №7

Discover a straightforward method for looping through an array from any given index, moving both forward and backward simultaneously. This approach allows you to iterate through the items starting with those closest to the index and then expanding outwards.

let result = 0;
function traverseFromMiddle(arr, idx) {
    let newArray = [];
    const shorterLength = Math.min(idx, arr.length - idx);
    for (let i = 0; i < shorterLength; i++) {
        newArray.push(arr[idx + i]); // add next
        newArray.push(arr[idx - i - 1]); // add previous
    }
    for (let i = idx + shorterLength; i < arr.length; i++) {
        newArray.push(arr[i]); // add remaining elements on right side
    }
    for (let i = idx - shorterLength - 1; i > -1; i--) {
        newArray.push(arr[i]); // add remaining elements on left side
    }
    return newArray;
}
var array = [...Array(10).keys()]; // 0,1,2,3,4,5,6,7,8,9
result += traverseFromMiddle(array, 0) == '0,1,2,3,4,5,6,7,8,9' ? 1 : 0;
result += traverseFromMiddle(array, 2) == '2,1,3,0,4,5,6,7,8,9' ? 1 : 0;
result += traverseFromMiddle(array, 4) == '4,3,5,2,6,1,7,0,8,9' ? 1 : 0;
result += traverseFromMiddle(array, 5) == '5,4,6,3,7,2,8,1,9,0' ? 1 : 0;
result += traverseFromMiddle(array, 7) == '7,6,8,5,9,4,3,2,1,0' ? 1 : 0;
result += traverseFromMiddle(array, 9) == '9,8,7,6,5,4,3,2,1,0' ? 1 : 0;

// Same algorithm implemented as a generator function
function* traverseFromMiddleG(arr, idx) {
    const shorterLength = Math.min(idx, arr.length - idx);
    for (let i = 0; i < shorterLength; i++) {
        yield arr[idx + i]; // add next
        yield arr[idx - i - 1]; // add previous
    }
    for (let i = idx + shorterLength; i < arr.length; i++) {
        yield arr[i]; // add remaining elements on right side
    }
    for (let i = idx - shorterLength - 1; i > -1; i--) {
        yield arr[i]; // add remaining elements on left side
    }
}
var array2 = [...Array(7).keys()]; // 0,1,2,3,4,5,6
result += [...traverseFromMiddleG(array2, 0)] == '0,1,2,3,4,5,6' ? 1 : 0;
result += [...traverseFromMiddleG(array2, 1)] == '1,0,2,3,4,5,6' ? 1 : 0;
result += [...traverseFromMiddleG(array2, 3)] == '3,2,4,1,5,0,6' ? 1 : 0;
result += [...traverseFromMiddleG(array2, 5)] == '5,4,6,3,2,1,0' ? 1 : 0;
result += [...traverseFromMiddleG(array2, 6)] == '6,5,4,3,2,1,0' ? 1 : 0;
console.log(`Achieved ${result} out of 11 tests`);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Executing JavaScript upon inserting it into the HTML of a webpage

On a webpage, I have content that is first sent from the server at page load and then frequently updated via AJAX. To handle this, I currently use $( function () {} ) for binding and updating based on the initial server data. However, I also need a way to ...

Determine the presence of a JSON Value/Array in a web application using JavaScript and visualize the information in a dynamic

Utilizing the Ticketmaster API has provided me with a sample dataset from their platform, Data 1 - Including information on "presales." "sales": { "public": { "startDateTime": "2019-11 ...

How to Retrieve the Size Measurements of a 3D Model Using JavaScript

Currently, I am involved in an AR project that utilizes three.js and involves working with various 3D models. One issue I have encountered is the inconsistency in sizes among the models. I aim to have all the models of the same size, which requires setting ...

Solving layout issues / Techniques for determining element heights

This new question is in relation to my previous one: How to position relative elements after absolute elements I have updated the JsFiddle from that question to better represent my current HTML, which I unfortunately do not have a URL for at the moment. Y ...

Issue encountered when trying to test a slider element using TestCafe

Could someone please help me with writing a test for a slider element in this situation? <Slider defaultValue={pickupValue.length ? pickupValue : [15, 15]} aria-labelledby="range-slider" ...

Determine the necessary camera zoom level to ensure the object fits within the height of the screen

In my Three.js project, I've been utilizing these formulas to determine the visible width and height: var vFOV = camera.fov * Math.PI / 180; // converting vertical fov to radians var height = 2 * Math.tan( vFOV / 2 ) * dist; // calculating vis ...

Passing events from one controller to another in AngularJS using methods such as $broadcast and $window.localStorage

Looking to dispatch an event to another controller, I am familiar with techniques involving $rootScope.$broadcast, $scope.$emit, and then listening for the event using $scope.$on. This is a common approach, but in my project, controllers are initialized i ...

Managing Z-index (navigation) in Java Selenium 2.0 by addressing z-index conflicts prior to executing the built-in scroll function followed by the WebElement

When using Selenium 2.0, the .click() method has the capability to automatically scroll until the element is visible and can be clicked on, as shown in the code snippet below: WebElement box = driver.findElement( By.id( boxID ) ); box.click(); Generally, ...

Is there a way for me to determine the total number of seconds since the chatbot was first opened?

Here is a snippet of my HTML code: <div class="chatbot chatbot--closed "> <div class="chatbot__header"> <p><strong>Got a question?</strong> <span class="u-text-highlight">Ask Harry</span></p> <s ...

What is the best way to delete table rows based on their assigned class?

Within my HTML document, there is the following structure: <table id="registerTable"> <tr class="leaderRegistration"> <!--table contents--> </tr> <tr class="leaderRegistration"> <!--table conten ...

Conditions for JQuery Ajax handlingIs there anything specific you would

I am looking to implement a try-catch scenario in Laravel where, if successful, a certain message will appear and if it fails, a different message will be displayed. However, when executed successfully, it seems to display the second message instead. $.a ...

Merging several mysql queries to generate a consolidated outcome

I am working with PHP to retrieve data from a MySQL table. I need to execute multiple conditional statements to display a list of unique results. Let's consider a scenario where I have a table containing information about houses on my street, structur ...

Struggling with implementing Game of Life using dynamic arrays in C++

I am currently working on programming the game of life. I'm facing some issues while iterating generations and end up with unexpected results. Despite trying various approaches, I can't seem to find the error in my logic. Any guidance or assistan ...

Invalid data type in Mongoose schema configuration

I am facing a situation where I have defined a schema similar to the following: analytics: { visits: { amounts: { type: Array, default: [] }, dates: { type: Array, default: [] } }, }, Howe ...

What is the best method for adding a   character within the @Html.DisplayFor() method when referencing m.EventDetailSection.ContactAccountTel?

At the moment, my code looks like this: @Html.DisplayFor(m => m.EventDetailSection.ContactAccountTel), which displays the phone number without any spaces, such as +3194949494. I want to format it with spaces after every 2 numbers and then after every ...

Encountering issues with the phaser framework while setting up a server on xampp, faced with errors in javascript and html

Recently, I've been working on a game using Phaser and encountered some issues while trying to run the code in XAMPP. The game's base is located at htdocs/itw/test.html, with the necessary pngs and json file stored in htdocs/itw/assets/. The pngs ...

Exploring a React JS option for filtering repeated elements, as an alternative to Angular

While using Angular JS, I came across the 'filter' option within ng-repeat which is useful for live search. Here's an example: <div ng-repeat="std in stdData | filter:search"> <!-- Std Items go here. --> </div> &l ...

An External Force is Disrupting My Jquery

Something seems off because everything was working perfectly fine until the FallingLeavesChristmas.min.js file stopped activating on this specific page. I initially thought it was an issue with the JavaScript itself, but that doesn't seem to be the ca ...

Eliminate item from nested array when the array is devoid of elements in Typescript

If the nested array is empty and I want to remove the object, how can I achieve this? For example, consider the following array: pokemonGroups = [ { name: 'Grass', pokemon: [ 'bulbasaur-0', 'Bulbasaur' ...

What is the best way to restrict the creation of objects in a JavaScript list?

Experiencing a fun challenge with HTML coding! Take a look at my ordered list in HTML: <ol id="myList"> <li>Tea</li> <li>Milk</li> <li>Water</li> </ol> <button onclick="myFunction()">Try it</ ...