jonin
jonin

Reputation: 232

Sort a single dimensional array by the indexes listed in second single demential array - JavaScript

Here is the situation: I need the ability to reorder any single dimensional array so that the new array starts with the center number(if object count is odd) or the center 2 numbers (if object count is even) and iterates low, then high until all numbers in original array are accounted for.

Example 1 - odd number of objects: Original Array: [1,2,3,5,8,13,20] New Array: [5,3,8,2,13,1,20]

Example 2 - even number of objects: Original Array: [1,2,3,4] New Array: [2,3,1,4]

I have tried this with a for loop and can get it to work hypothetically, but I am not able to use a for loop as a computed property in Vue.js.


Here is my attempt which does not work:

gameInfo: {
      cards: [1, 2, 3, 6, 8, 13, 21, 40, 1000],
    }

reorderOddCards() {
  ATTEMPT 1
  const cardCount = this.gameInfo.cards.length;
  const middleNumber = (cardCount / 2).toFixed(0);
  const newCardOrder = this.gameInfo.cards.map(addToArray);

  function addToArray(value, index) {
    if (index < middleNumber) {
      const newIndex = (((middleNumber - index) * 2) - 1);
      newCardOrder.splice(newIndex, 1, value);
    } else if (index === middleNumber) {
      newCardOrder.splice(index, 1, value);
    } else {
      const newIndex = ((middleNumber - index) * 2);
      newCardOrder.splice(newIndex, 1, value);
    }
  }

  return newCardOrder;
},

Here is a seemingly better approach with a .sort function, but I can't seem to get it working either.

Potential Solution

Upvotes: 1

Views: 63

Answers (1)

Unmitigated
Unmitigated

Reputation: 89264

This can be achieved with a simple while loop. The key here is finding the middle index(es). In an odd length array, there is only one center, which we can think of as having the left and right centers on the same point to generalize the solution. This index will be the result of flooring the length divided by two. The right index will always be this value as well. However, for even length arrays, we need to decrement the left index by one. After computing these indexes, we loop while decrementing the left index and incrementing the right index to add values to our result array.

function order(arr){
  let right = Math.floor(arr.length / 2);
  let left = right - (arr.length % 2 == 1 ? 0: 1);
  let res = left === right ? [arr[left]] : arr.slice(left, right + 1);
  while(left > 0){
    res.push(arr[--left]);
    res.push(arr[++right]);
  }
  return res;
}
console.log(...order([1,2,3,5,8,13,20]));
console.log(...order([1,2,3,4]));

Upvotes: 1

Related Questions