Обратные пары элементов в массиве

#javascript #arrays #sorting #reverse

#javascript #массивы #сортировка #обратный

Вопрос:

Рассмотрим массив

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

Я хочу отсортировать это таким образом

 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]
  

Как я могу добиться РЕЗУЛЬТАТА без необходимости проходить через массив, как в reversePairs ? Я заинтересован в сортировке их по их индексам, а не по их значениям.

Спасибо.

Комментарии:

1. Всегда ли сортируется ваш исходный массив?

2. Да, и в очень специфическом порядке (кубические точки Безье).

Ответ №1:

если arr.length — четное число (массив пар), то

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

Ответ №2:

Вы можете перебирать пары, менять их местами и в конце инвертировать результирующий массив:

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

Ответ №3:

Вы могли бы взять половину целого числа за дельту и отсортировать остальное по возрастанию.

 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]  

Комментарии:

1. Спасибо за этот интересный ответ. Меня интересует сортировка их не по их значениям, а по их индексам.

2. просто возьмите массив и сопоставьте нужные значения.

3. Хотя этот ответ не совсем то, что я искал, он определенно надежный. Спасибо

Ответ №4:

Этот подход не самый эффективный, но он более удобочитаемый. В основном мы используем reduce() для перебора каждого значения, и если текущее index % 2 == 0 , то это первое значение пары, поэтому мы unshift создаем новый массив с самого начала. если index % 2 == 1 мы добавим значение в первый массив. Затем мы вызываем flat() , чтобы объединить несколько парных массивов в один.

Это не самый эффективный способ, потому что нам приходится перебирать все дважды и создавать несколько промежуточных массивов. Если ваш список значений очень большой (тысячи значений или более) Я бы использовал метод ниже. Если нет, я бы использовал это, поскольку это проще для понимания.

 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 resu<
 }, [])
 .flat();
 
 console.log(output);  

Этот метод выполняет все это с одним массивом за один цикл:

 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 resu<
}, []);

console.log(output);  

На мой взгляд, это немного сложнее для понимания, но это работает, потому что конечный массив будет одинаковой длины, поэтому мы в основном просто получаем его обратный индекс, а затем сдвигаем его вверх или вниз на единицу в зависимости от того, является ли это первым или вторым значением ( index % 2 == 0 или index % 2 == 1 ) в паре.

Комментарии:

1. Есть ли преимущество у этого метода по сравнению с тем, который я выбрал?

2. Не совсем. Мое решение, возможно, немного более читабельно, поскольку математика не такая абстрактная, но лишь чуть-чуть. Выбранный вами ответ является надежным.

Ответ №5:

Массив может содержать что угодно.. порядок будет таким, как вы хотели!

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

Ответ №6:

… простой и зависит от четного числа элементов массива…

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

… или на основе Array.prototype.reduceRight и полностью независимо от количества элементов любого массива …

 function collectPairWiseFromRight(collector, item, idx, arr) {
  if (((idx % 2) === 0) amp;amp; (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; }