492 Stimmen

Wie kann man ein Array sortieren, ohne das ursprüngliche Array zu verändern?

Nehmen wir an, ich wollte eine Sortierfunktion, die eine sortierte Kopie des eingegebenen Arrays zurückgibt. Ich habe naiverweise Folgendes versucht

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

und ich habe es damit getestet, was zeigt, dass meine sort Methode verändert das Array.

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"

Ich habe auch diesen Ansatz ausprobiert

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

aber es funktioniert überhaupt nicht.

Gibt es eine einfache Möglichkeit, um dies zu umgehen, vorzugsweise ein Weg, der nicht Hand-Rolling meine eigenen Sortieralgorithmus oder Kopieren jedes Element des Arrays in eine neue erfordert?

1 Stimmen

Eine tiefe Kopie des Arrays erstellen und es stattdessen sortieren.

2 Stimmen

@evanmcdonnal Eine flache Kopie könnte ausreichen, wenn alles, was gewünscht ist, ist eine Neuordnung und nicht ein Duplikat von jedem Element in dem Array.

0 Stimmen

.sort erfordert die this Wert das Array sein. Damit das letzte Snippet funktioniert, müssen Sie also .sort.call(arr) (obwohl das Ihr Problem nicht löst).

524voto

Putzi San Punkte 4658

Sie müssen das Array kopieren, bevor Sie es sortieren. Eine Möglichkeit mit es6:

const sorted = [...arr].sort();

Die Spread-Syntax als Array-Literal (kopiert von mdn):

var arr = [1, 2, 3];
var arr2 = [...arr]; // like arr.slice()

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator

0 Stimmen

Das ist wirklich toll. Ich denke, es ist einfacher zu verstehen als Concat und andere Ansätze.

0 Stimmen

Dieser Code funktioniert, aber wenn ich die JS mit Gulp kompilieren kommt es zurück mit einem Fehler, SyntaxError: Unerwartetes Token: punc (.)

6 Stimmen

Für diejenigen, die sagen, es sei kein gültiges JavaScript... es ist absolut gültig. Wenn Sie in Chrome/Safari/Edge oder Firefox arbeiten: Öffnen Sie die Dev-Konsole, definieren Sie ein Array namens arr und fügen Sie den Ausdruck ein, um das Ergebnis zu sehen.

259voto

Rob W Punkte 327048

Kopieren Sie einfach das Array. Es gibt viele Möglichkeiten, das zu tun:

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

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

4 Stimmen

Wird dies eine tiefe Kopie machen, d.h. werden verschachtelte Objekte und Arrays auch kopiert werden?

3 Stimmen

Gibt es einen Vorteil bei der Verwendung von concat über Mitsprache slice(0) oder sind sie alle so ziemlich das Gleiche?

0 Stimmen

@JaredPar Das Ergebnis ist gleich. Wenn Sie wirklich auf Mikro-Performance aus sind, können Sie einen Perf-Check einrichten (oder nachschlagen) unter jsperf.com

82voto

JaredPar Punkte 699699

Versuchen Sie Folgendes

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

En slice(0) Ausdruck erstellt eine Kopie des Arrays beginnend bei Element 0.

57voto

zzzzBov Punkte 166065

Sie können slice ohne Argumente verwenden, um ein Array zu kopieren:

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

0 Stimmen

Diese Antwort ist großartig! Ich bin überrascht, dass JavaScript Mutation in diesem Ausmaß zulässt. Scheint falsch zu sein. Nochmals vielen Dank.

0 Stimmen

Seine nicht eine Mutation, Sie sind oberflächlich Kopieren foo Array in bar Variable.

21voto

Aditya Agarwal Punkte 703

Sie können auch Folgendes tun

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

Auf diese Weise kann d nicht mutiert werden.

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

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

0 Stimmen

Diese Antwort ist nett

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X