2012-03-06 10 views
87

入力された配列のソートされたコピーを返すソート関数が必要だったとしましょう。私は単純に、このどのように元の配列を変更せずに配列をソートできますか?

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

を試みたが、それがすべてでは動作しません。

これは単純に私自身のソートアルゴリズムを手で動かしたり、配列のすべての要素を新しいものにコピーしたりする必要がない方法ですか?

+0

アレイのディープコピーを作成し、代わりに並べ替えます。 – evanmcdonnal

+0

@evanmcdonnal浅いコピーは、すべてが必要な場合は配列のすべての項目の並べ替えではなく、重複ではありません。 – Kekoa

+0

'.sort'は' this'値が配列であることを要求します。最後のスニペットが機能するには '.sort.call(arr)'を実行します(問題は解決しません)。 – pimvdb

答えて

101

配列をコピーするだけです。それを行うには多くの方法があります:

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

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

これはディープコピー、つまりネストされたオブジェクトや配列もコピーされますか? –

+0

'slice(0)'と比べて 'concat'を使う利点はありますか、それともまったく同じですか? – JaredPar

+0

@JaredPar結果は等しくなります。あなたがマイクロパフォーマンスを本当に追っているなら、http://jsperf.com/ –

32

slice(0)式はあなたが引数なしでスライスを使用することができます要素0

+18

+1、 '.slice()'も機能します。 – pimvdb

16

から始まる配列のコピーを作成し、以下の

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

をお試しください配列をコピーする:

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

は私のためにコピーしません – Rbjz

+2

@ RobertCutajar-Robajz、そのスニペットをそのままデベロッパーコンソールにコピーしてください。うまくいくでしょう。問題がある場合は、この回答のコードではありません。 – zzzzBov

+0

真実、私はスクリプトをキャッシュしていました。できます。 – Rbjz

-1

私は私のコピーのほとんどのためObject.assign()を使用します。

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

しかし、OPのコメントを見た後、私は深いコピーのビットを調査していないだけで、浅いコピーを実行するだけでなく、唯一の選択Object.assignが判明します(this postで回答されているように)列挙可能なプロパティを持ちます。 ES6と非深いコピーの

0

ますこれもできます

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

この方法では変異しません。

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

//Use it like this 
x = [20, 10, 100] 
console.log(sorted(x)) 
関連する問題