thednp
thednp

Reputation: 4479

Reverse pairs of items in array

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.

Upvotes: 1

Views: 939

Answers (6)

Peter Seliger
Peter Seliger

Reputation: 13432

... 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; }

Upvotes: 0

samanime
samanime

Reputation: 26607

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.

Upvotes: 1

Andrii Biletskyi
Andrii Biletskyi

Reputation: 165

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))

Upvotes: 2

rainerbez
rainerbez

Reputation: 11

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());

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386680

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]

Upvotes: 1

Majed Badawi
Majed Badawi

Reputation: 28424

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

Upvotes: 1

Related Questions