1

Consider the array

let myArray = [0,1,2,3,4,5,6,7]

I want to sort it this way

let reversedPairs = [myArray[6],myArray[7],myArray[4],myArray[5],myArray[2],myArray[3],myArray[0],myArray[1]]
// RESULT [6,7,4,5,2,3,0,1]

How can I achieve the RESULT without having to go through the array like in reversePairs? I'm interested in sorting them by their indexes and not their values.

Thank you.

2
  • Is your initial array always sorted? Commented Aug 20, 2020 at 12:10
  • Yes, and very specific order (cubic bezier points). Commented Aug 20, 2020 at 12:11

6 Answers 6

2

if arr.length is an even number(array of pairs) than

const arr = [0, 1, 2, 3, 4, 5, 6, 7]

const reversePairs = arr => arr.map((_, i) => arr[arr.length - i - 2 * (1 - i % 2)])

console.log(reversePairs(arr))

Sign up to request clarification or add additional context in comments.

Comments

1

You can iterate over the pairs, swap them, and reverse the resulting array in the end:

let myArray = [0,1,2,3,4,5,6,7];
for(let i = 0; i < myArray.length-1; i+=2){
     let temp = myArray[i];
     myArray[i] = myArray[i+1];
     myArray[i+1] = temp;
}
myArray = myArray.reverse();
console.log(myArray);

Comments

1

You could take the integer half for the delta and sort the rest ascending.

let values = ['a', 'b', 'c', 'e', 'f', 'g', 'h', 'i'],
    result = [...values.keys()]
        .sort((a, b) => (b >> 1) - (a >> 1)  || a - b) // or Math.floor(a / 2)
        .map(i => values[i]);

console.log(...result); // [6, 7, 4, 5, 2, 3, 0, 1]

3 Comments

Thanks for this interesting answer. I'm not interested in sorting them by their values, but by their indexes.
just take the array an map the wanted values.
While this answer isn't exactly what I was looking for, it's definitely solid. Thank you
1

This approach isn't the most efficient, but it is more readable. Basically we use reduce() to loop through each value and if the current index % 2 == 0 it is the first value of the pair, so we unshift a new array to the beginning. if index % 2 == 1 we add the value to the first array. Then we call flat() to combine the multiple pair arrays into one.

It's not the most efficient because we have to loop through everything twice and create some intermediate arrays. If you're list of values is super large (thousands of values or more) I would use the method further down. If not, I'd use this as it is easier to understand.

const input = [0,1,2,3,4,5,6,7];
const output = input
 .reduce((result, value, index) => {
  index % 2 == 0 ? result.unshift([value]) : result[0].push(value);
  return result;
 }, [])
 .flat();
 
 console.log(output);

This method gets it all done with one array in one loop:

const input = [0,1,2,3,4,5,6,7];
const length = input.length;
const output = input.reduce((result, value, index) => {
  const reversedIndex = length - index - 1;
  result[reversedIndex % 2 == 0 ? reversedIndex + 1 : reversedIndex - 1] = value;
  return result;
}, []);

console.log(output);

In my opinion, it is a little harder to understand, but it works because the final array is going to be the same length, so we basically just get its reversed index, and then shift it up or down by one based on if it is the first or second value (index % 2 == 0 or index % 2 == 1) in the pair.

2 Comments

Is there an advantage to this method over the one I've chosen?
Not really. My solution is maybe a tiny bit more readable as the math isn't quite as abstract, but only a teeny tiny bit. The answer you chose is a solid one.
0

Array can contain anything.. the order will be as you wanted it!

let myArray = [0,1,2,3,4,5,6,7];
myArray.reverse();
let my2=myArray.map((num,index,myArray)=>
  (index%2===0?[]:[num,myArray[index-1]])
);
console.log(my2.flat());

Comments

0

... straightforward and depended on an even number of array items ...

let myArray = [0, 1, 2, 3, 4, 5, 6, 7]

function getReorderedArrayPairWiseFromRight(arr) {
  const itemCount = arr.length;

  let idx = itemCount;
  let list = [];

  while (list.length < itemCount) {
    idx = (idx - 2);
    list = list.concat(arr.slice(idx, (idx + 2)));
  }
  return list;
}

console.log(myArray);
console.log(getReorderedArrayPairWiseFromRight(myArray));
.as-console-wrapper { min-height: 100%!important; top: 0; }

... or based on Array.prototype.reduceRight and totally agnostic to any array's item count ...

function collectPairWiseFromRight(collector, item, idx, arr) {
  if (((idx % 2) === 0) && (idx < (arr.length - 1))) {

    collector.push(arr[idx]);
    collector.push(arr[idx + 1]);
  }
  return collector;
}

console.log(
  [0, 1, 2, 3, 4, 5, 6, 7].reduceRight(collectPairWiseFromRight, [])
);
console.log(
  [0, 1, 2, 3, 4, 5, 6, 7, 8].reduceRight(collectPairWiseFromRight, [])
);

console.log(
  [0, 1, 2, 3, 4, 5, 6].reduceRight(collectPairWiseFromRight, [])
);
console.log(
  [0, 1, 2, 3, 4, 5].reduceRight(collectPairWiseFromRight, [])
);

console.log(
  [0, 1].reduceRight(collectPairWiseFromRight, [])
);

console.log(
  [0].reduceRight(collectPairWiseFromRight, [])
);
console.log(
  [].reduceRight(collectPairWiseFromRight, [])
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.