Array.prototype.reverse инвертирует содержимое массива на месте (с мутацией) ...
Существует ли такая же простая стратегия обращения массива без изменения содержимого исходного массива (без мутации)?
Array.prototype.reverse инвертирует содержимое массива на месте (с мутацией) ...
Существует ли такая же простая стратегия обращения массива без изменения содержимого исходного массива (без мутации)?
Ответы:
Вы можете использовать slice (), чтобы сделать копию, а затем перевернуть () ее
var newarray = array.slice().reverse();
В ES6:
const newArray = [...array].reverse()
[...].reverseпреимущество в очень простом тестовом примере. jsperf.com/reverse-vs-slice-reverse/1
.sliceзначительно быстрее.
slice, скорее всего, будет быстрее, [...]потому что b / c - это итеративный массив, поэтому он не может делать столько предположений. Кроме того, вероятно, что sliceон лучше оптимизирован, потому что это было давно.
Еще один вариант ES6:
Мы также можем использовать .reduceRight()для создания обращенного массива, фактически не обращая его.
let A = ['a', 'b', 'c', 'd', 'e', 'f'];
let B = A.reduceRight((a, c) => (a.push(c), a), []);
console.log(B);
Полезные ресурсы:
reduceRightмедленный аф
(a, c) => a.concat([c])чувствует себя более идиоматичным, чем(a, c) => (a.push(c), a)
Попробуйте это рекурсивное решение:
const reverse = ([head, ...tail]) =>
tail.length === 0
? [head] // Base case -- cannot reverse a single element.
: [...reverse(tail), head] // Recursive case
reverse([1]); // [1]
reverse([1,2,3]); // [3,2,1]
reverse('hello').join(''); // 'olleh' -- Strings too!
ES6 альтернативное использование .reduce()и распространение.
const foo = [1, 2, 3, 4];
const bar = foo.reduce((acc, b) => ([b, ...acc]), []);
По сути, он создает новый массив со следующим элементом в foo и распределяет накопленный массив для каждой итерации после b.
[]
[1] => [1]
[2, ...[1]] => [2, 1]
[3, ...[2, 1]] => [3, 2, 1]
[4, ...[3, 2, 1]] => [4, 3, 2, 1]
В .reduceRight()качестве альтернативы, как упомянуто здесь выше, но без .push()мутации.
const baz = foo.reduceRight((acc, b) => ([...acc, b]), []);
Существует несколько способов обращения массива без изменений. Двое из них
var array = [1,2,3,4,5,6,7,8,9,10];
// Using Splice
var reverseArray1 = array.splice().reverse(); // Fastest
// Using spread operator
var reverseArray2 = [...array].reverse();
// Using for loop
var reverseArray3 = [];
for(var i = array.length-1; i>=0; i--) {
reverseArray.push(array[i]);
}
Тест производительности http://jsben.ch/guftu
В простой Javascript:
function reverseArray(arr, num) {
var newArray = [];
for (let i = num; i <= arr.length - 1; i++) {
newArray.push(arr[i]);
}
return newArray;
}
Реверсирование на месте с переменным обменом только для демонстрационных целей (но вам нужна копия, если вы не хотите изменять)
const myArr = ["a", "b", "c", "d"];
const copy = [...myArr];
for (let i = 0; i < (copy.length - 1) / 2; i++) {
const lastIndex = copy.length - 1 - i;
[copy[i], copy[lastIndex]] = [copy[lastIndex], copy[i]]
}
ES6:
const reverseArr = [1,2,3,4].sort(()=>1)
1в конце могло бы быть больше нуля, потому что именно так работает Array.prototype.sortобратный вызов (или так называемый compare function). В основном вы всегда сравниваете 2 числа, и в этом случае сравнение возвращает всегда положительное значение, поэтому оно говорит, что всегда переходите ко второму числу перед первым :) это очень объяснительно: stackoverflow.com/questions/6567941/…
sort()мутирует массив (т.е. сортирует его на месте), чего хочет избежать OP.