원래 배열을 변경하지 않고 Javascript로 배열을 뒤집습니다.


188

Array.prototype.reverse (돌연변이로) 배열의 내용을 뒤집습니다.

원래 배열의 내용을 변경하지 않고 (돌연변이없이) 배열을 뒤집는 비슷한 전략이 있습니까?



여기에 다른 옵션을 비교하는 벤치 마크는 다음과 같습니다 jsben.ch/HZ7Zp
솔로몬 Ucko

답변:


375

당신은 사용할 수 있습니다 slice ()를 복사 한 다음 수 있도록 () 역

var newarray = array.slice().reverse();


매개 변수없이 slice ()를 설명해 주시겠습니까?
Alex

3
@ 알렉스 슬라이스 - If begin is omitted, slice begins from index 0.- 그래서 같이 동일array.slice(0)
룬 P Johny는

2
@Alex는 '답변으로 설명하십시오'... 어쨌든 ... 훌륭한 솔루션을 의미한다고 생각합니다. 감사!
sfletche

13
이 방법은 오도의 여지가 있으므로 사용하지 않는 것이 좋습니다. slice ()를 사용할 때 실제로 혼란스럽고 실제로는 슬라이스하지 않습니다. 당신은 불변의 역을해야하는 경우, 단지 신선한 새 복사본을 만들 : CONST newArray = [... 배열] .reverse ()
올렉 Matei

105

ES6에서 :

const newArray = [...array].reverse()

2
이것의 성능은 수용 된 답변의 성능과 어떻게 비교됩니까? 그들은 같은가요?
Katie

@Katie Chrome [...].reverse은 매우 간단한 테스트 사례에서 우위를 점하는 것처럼 매우 빠르며 매우 유사 합니다. jsperf.com/reverse-vs-slice-reverse/1
Brian M. Hunt

4
꾸준히 .slice빨라지고 있습니다.
James Coyle

3
@JamesCoyle 아마도 브라우저와 OS에 따라 다르지만 slice더 빠를 가능성이 높습니다. b / c [...]는 일반적인 반복 가능한 배열이므로 많은 가정을 할 수 없습니다. 또한 slice오래 전부터 사용되어 온 b / c가 더 최적화 되었을 가능성이 높습니다 .
Brian M. Hunt

내 생각과 일치 해.
James Coyle

11

또 다른 ES6 변형 :

.reduceRight()실제로 뒤집지 않고 역 배열을 만드는 데 사용할 수도 있습니다 .

let A = ['a', 'b', 'c', 'd', 'e', 'f'];

let B = A.reduceRight((a, c) => (a.push(c), a), []);

console.log(B);

유용한 자료 :


2
reduceRight느린 속도
Dragos Rizescu

@DragosRizescu 샘플 테스트 결과를 공유 할 수 있습니까?
Mohammad Usman

1
여기에 당신이 가지고 놀 수있는 레포가 있습니다 : (가장 좋은 예는 아니지만 React 컨텍스트에서 누군가 와이 논쟁을 한 적이 있기 때문에 함께 정리했습니다) : github.com/rizedr/reduce-vs-reduceRight
Dragos Rizescu

4
(a, c) => a.concat([c])보다 더 관용적 느낌(a, c) => (a.push(c), a)
카일 린

1
@DragosRizescu 실제로 이것이 3 가지 답변 중 가장 빠른 것 같습니다. jsperf.com/reverse-vs-slice-reverse/3
DBosley

7

이 재귀 솔루션을 사용해보십시오.

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!                              

1
빈 배열에서는 깨질 것 같습니다.
Matthias

6

사용 .reduce()및 확산 의 ES6 대안 .

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

4

수정하지 않고 배열을 뒤집는 방법에는 여러 가지가 있습니다. 그들 중 두

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


0

일반 자바 스크립트로 :

function reverseArray(arr, num) {
  var newArray = [];
  for (let i = num; i <= arr.length - 1; i++) {
    newArray.push(arr[i]);
  }

  return newArray;
}

0

설명을 위해 변수 스왑을 사용하여 뒤집기 (그러나 변경하지 않으려면 사본이 필요함)

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


-4

es6 :

const reverseArr = [1,2,3,4].sort(()=>1)

4
SO, Radion에 오신 것을 환영합니다! 답변을 남길 때 일반적으로 답변의 효과와이 결론에 도달 한 이유를 설명하는 것이 좋습니다. 이는 새로운 사용자가 지정한 상호 작용 및 언어를 이해하는 데 도움이됩니다.
Ethan Field

Radion의 방어에서 : P 1는 결국 0보다 클 수 있습니다. Array.prototype.sort콜백 (또는 소위 compare function)이 작동 하는 방식이기 때문입니다 . 기본적으로 당신은 항상이 개 숫자를 비교하고,이 경우 항상 처음의 앞에 두 번째 번호로 이동 말합니다 있도록 항상 긍정적 인 비교 반환 :)이 매우 설명입니다 : stackoverflow.com/questions/6567941/...
iulial

8
sort()OP를 피하기 위해 배열을 변경 (즉, 정렬)합니다.
클린트 해리스

5
이 대답은 여러 가지면에서 잘못되었습니다. (1) @ClintHarris가 지적한 것처럼 배열을 변경하므로 .reverse ()보다 낫지 않습니다. (2) 비교기는 불법입니다. a, b에 대해 1을 반환하면 b, a에 대해 음수를 반환해야합니다. 귀하의 답변이 일부 구현에서 배열을 반대로 바꾸면 전적으로 운입니다.
돈 해치
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.