1464 Stimmen

Wie man ein bestehendes JavaScript-Array mit einem anderen Array erweitert, ohne ein neues Array zu erstellen

Es scheint keine Möglichkeit zu geben, ein bestehendes JavaScript-Array mit einem anderen Array zu erweitern, d.h. Pythons extend Methode.

Ich möchte Folgendes erreichen:

>>> a = [1, 2]
[1, 2]
>>> b = [3, 4, 5]
[3, 4, 5]
>>> SOMETHING HERE
>>> a
[1, 2, 3, 4, 5]

Ich weiß, es gibt eine a.concat(b) Methode, aber sie erstellt ein neues Array, anstatt einfach das erste zu erweitern. Ich hätte gerne einen Algorithmus, der effizient arbeitet, wenn a deutlich größer ist als b (d.h. eine, die nicht kopiert a ).

<em><strong>Nota: </strong>Dies ist <strong>nicht ein Duplikat von <a href="https://stackoverflow.com/questions/351409/appending-to-array">Wie kann man etwas an ein Array anhängen? </a></strong>-- Ziel ist es hier, den gesamten Inhalt eines Arrays dem anderen hinzuzufügen, und zwar "an Ort und Stelle", d.h. ohne alle Elemente des erweiterten Arrays zu kopieren.</em>

10 Stimmen

Aus @Zahnbürste's Kommentar zu einer Antwort: a.push(...b) . Das Konzept ähnelt dem der ersten Antwort, wurde aber für ES6 aktualisiert.

0 Stimmen

>>> a.push(...b)

48voto

Alireza Punkte 92209

Zunächst ein paar Worte über apply() in JavaScript, um zu verstehen, warum wir es verwenden:

Le site apply() Methode ruft eine Funktion mit einem bestimmten this Wert, und Argumente, die als Array bereitgestellt werden.

Push erwartet eine liste der Elemente, die dem Array hinzugefügt werden sollen. Die apply() Methode nimmt jedoch die erwarteten Argumente für den Funktionsaufruf als Array entgegen. Dies ermöglicht es uns, einfach push die Elemente eines Arrays in ein anderes Array mit dem eingebauten push() Methode.

Stellen Sie sich vor, Sie haben diese Arrays:

var a = [1, 2, 3, 4];
var b = [5, 6, 7];

und tun Sie dies einfach:

Array.prototype.push.apply(a, b);

Das Ergebnis wird sein:

a = [1, 2, 3, 4, 5, 6, 7];

Das Gleiche kann in ES6 mit dem Spread-Operator (" ... ") wie folgt:

a.push(...b); //a = [1, 2, 3, 4, 5, 6, 7]; 

Kürzer und besser, aber derzeit noch nicht von allen Browsern unterstützt.

Auch wenn Sie umziehen alles von Array b zu a Entleerung b Dabei können Sie Folgendes tun:

while(b.length) {
  a.push(b.shift());
} 

und das Ergebnis wird wie folgt aussehen:

a = [1, 2, 3, 4, 5, 6, 7];
b = [];

39voto

Jules Colle Punkte 10421

Wenn Sie jQuery verwenden möchten, gibt es $.merge()

Beispiel:

a = [1, 2];
b = [3, 4, 5];
$.merge(a,b);

Ergebnis: a = [1, 2, 3, 4, 5]

19voto

gman Punkte 91048

Wie die am häufigsten gewählte Antwort besagt, a.push(...b) ist wahrscheinlich die richtige Antwort, wenn man das Problem der Größenbeschränkung berücksichtigt.

Andererseits scheinen einige der Antworten zur Leistung veraltet zu sein.

Die folgenden Zahlen gelten für den 2022-05-20

enter image description here

enter image description here

enter image description here

von aquí

Es scheint, dass push im Jahr 2022 in allen Bereichen am schnellsten ist. Das könnte sich in Zukunft ändern.

Antworten, die die Frage ignorieren (Erstellung eines neuen Arrays), gehen am Thema vorbei. Viele Codes müssen/wollen möglicherweise ein Array an Ort und Stelle ändern, da es andere Referenzen auf dasselbe Array geben kann

let a = [1, 2, 3];
let b = [4, 5, 6];
let c = a;
a = a.concat(b);    // a and c are no longer referencing the same array

Diese anderen Referenzen könnten tief in einem Objekt stecken, etwas, das in einer Schließung erfasst wurde, usw..

Als wahrscheinlich schlechtes Design, aber zur Veranschaulichung, stellen Sie sich vor, Sie hätten

const carts = [
  { userId: 123, cart: [item1, item2], },
  { userId: 456, cart: [item1, item2, item3], },
];

und eine Funktion

function getCartForUser(userId) {
  return customers.find(c => c.userId === userId);
}

Dann möchten Sie Artikel in den Warenkorb legen

const cart = getCartForUser(userId);
if (cart) {
  cart.concat(newItems);      // FAIL 
  cart.push(...newItems);     // Success! 
}

Nebenbei bemerkt, die Antworten, die eine Änderung der Array.prototype sind wohl eine schlechte Werbung. Das Ändern der nativen Prototypen ist im Grunde eine Landmine in Ihrem Code. Eine andere Implementierung kann sich von Ihrer unterscheiden und so wird Ihr Code kaputt gehen oder Sie werden deren Code kaputt machen, der das andere Verhalten erwartet. Dies gilt auch, wenn eine native Implementierung hinzugefügt wird, die mit Ihrer kollidiert. Sie sagen vielleicht: "Ich weiß, was ich verwende, also ist das kein Problem", und das mag im Moment stimmen, wenn Sie ein einzelner Entwickler sind, aber fügen Sie einen zweiten Entwickler hinzu, und der kann Ihre Gedanken nicht lesen. Und Sie sind dieser zweite Entwickler in ein paar Jahren, wenn Sie es vergessen haben und dann irgendeine andere Bibliothek (Analytics?, Logging?, ...) auf Ihre Seite aufpfropfen und vergessen, welche Spuren Sie im Code hinterlassen haben.

Dies ist nicht nur eine Theorie. Im Netz gibt es unzählige Geschichten von Menschen, die auf diese Minen gestoßen sind.

Es gibt wohl nur wenige sichere Verwendungen für die Änderung des Prototyps eines nativen Objekts. Eine davon ist das Polyfilling einer bestehenden und spezifizierten Implementierung in einem alten Browser. In diesem Fall ist die Spezifikation definiert, die Spezifikation ist implementiert und wird in neuen Browsern ausgeliefert, man möchte nur das gleiche Verhalten in alten Browsern erreichen. Das ist ziemlich sicher. Pre-Parcheando (Spezifikation in Arbeit, aber noch nicht verfügbar) ist wohl nicht sicher. Specs ändern sich vor der Auslieferung.

18voto

Ich mag die a.push.apply(a, b) Methode, die oben beschrieben wurde, und wenn Sie möchten, können Sie jederzeit eine Bibliotheksfunktion wie diese erstellen:

Array.prototype.append = function(array)
{
    this.push.apply(this, array)
}

und verwenden Sie es wie folgt

a = [1,2]
b = [3,4]

a.append(b)

14voto

Rafał Dowgird Punkte 40450

Es ist möglich, dies zu tun mit splice() :

b.unshift(b.length)
b.unshift(a.length)
Array.prototype.splice.apply(a,b) 
b.shift() // Restore b
b.shift() // 

Aber obwohl es hässlicher ist, ist es nicht schneller als push.apply Zumindest nicht in Firefox 3.0.

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