Reputation: 232
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.
Upvotes: 1
Views: 63
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