원래 배열을 변경하지 않고 어떻게 배열을 정렬 할 수 있습니까?


230

입력 된 배열의 정렬 된 사본을 반환하는 정렬 함수를 원한다고 가정 해 봅시다. 나는 순진하게 이것을 시도했다.

function sort(arr) {
  return arr.sort();
}

그리고 이것을 테스트하여 내 sort방법이 배열을 변경하고 있음을 보여줍니다 .

var a = [2,3,7,5,3,7,1,3,4];
sort(a);
alert(a);  //alerts "1,2,3,3,3,4,5,7,7"

나는 또한이 접근법을 시도했다.

function sort(arr) {
  return Array.prototype.sort(arr);
}

그러나 전혀 작동하지 않습니다.

이 방법에 대한 간단한 방법이 있습니까? 가능하면 내 자체 정렬 알고리즘을 수동으로 롤링하거나 배열의 모든 요소를 ​​새 것으로 복사 할 필요가없는 방법이 있습니까?


1
배열의 깊은 사본을 생성하고 대신 정렬하십시오.
evanmcdonnal

1
@evanmcdonnal 모든 것을 원한다면 배열의 모든 항목을 복제하지 않고 얕은 사본만으로도 충분할 수 있습니다.
Kekoa

.sort필요 this당신이 할 일을 마지막 조각을위한 있도록 배열로 값을 .sort.call(arr)(이 문제가 해결되지 않습니다하지만).
pimvdb

@Kekoa 그래, 좋은 지적이야. 요소 자체가 아닌 요소의 순서 만 변경하려는 경우 더 많은 메모리를 소비 할 필요가 없습니다.
evanmcdonnal

zzzzBov의 방법은 매력처럼 작동합니다! stackoverflow.com/a/9592774/7011860
Samet M.

답변:


222

배열을 복사하십시오. 여러 가지 방법이 있습니다.

function sort(arr) {
  return arr.concat().sort();
}

// Or:
return Array.prototype.slice.call(arr).sort(); // For array-like objects

2
이것은 깊은 복사를 수행합니까, 즉 중첩 된 객체 및 배열도 복사됩니까?
피터 올슨

2
과장된 concat말 을 사용하면 어떤 이점이 slice(0)있습니까? 아니면 모두 거의 동일합니까?
JaredPar

3
@PeterOlson 아니요, 얕은 사본입니다. 딥 카피를 원한다면 Stack Overflow의 검색 기능을 사용하여 기존의 훌륭한 답변을 찾으십시오.
Rob W

11
슬라이스는 이제 특히 빠른 것으로보고
잰더 갈색

3
Array.prototype.slice.call(arr).sort();대신에 arr.slice().sort();?
Olivier Boissé


61

다음을 시도하십시오

function sortCopy(arr) { 
  return arr.slice(0).sort();
}

slice(0)식은 요소 0 어레이 개시의 복사본을 생성한다.


32

인수없이 slice를 사용하여 배열을 복사 할 수 있습니다.

var foo,
    bar;
foo = [3,1,2];
bar = foo.slice().sort();

이 답변은 굉장합니다! JavaScript 가이 정도의 돌연변이를 허용한다는 사실에 놀랐습니다. 잘못된 것 같습니다. 다시 한번 감사합니다.

12

당신은 또한 이것을 할 수 있습니다

d = [20, 30, 10]
e = Array.from(d)
e.sort()

이러한 방식으로 d는 변이되지 않을 것이다.

function sorted(arr) {
  temp = Array.from(arr)
  return temp.sort()
}

//Use it like this
x = [20, 10, 100]
console.log(sorted(x))

이 답변은 훌륭합니다
Leasye

1

딥 카피를 수행하려는 사람은 (예 : 배열에 객체가 포함 된 경우) 다음을 사용할 수 있습니다.

let arrCopy = JSON.parse(JSON.stringify(arr))

그런 다음을 arrCopy변경하지 않고 정렬 할 수 있습니다 arr.

arrCopy.sort((obj1, obj2) => obj1.id > obj2.id)

참고 : 매우 큰 배열의 경우 속도가 느려질 수 있습니다.


이것은 두 번째 예제 -대신 작동 >합니다.
pootzko

0

필자 는 대부분의 복사본에 Object.assign () 을 사용합니다 .

var copyArray = Object.assign([], originalArray).sort();

그러나 OP 주석을 살펴본 후 약간의 깊은 복사를 연구하고 Object.assign이 얕은 복사를 수행 할뿐만 아니라 열거 할 수 있고 고유 한 속성 만 선택합니다 ( 이 게시물 에서 답변 ).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.