Ich suche nach einer JavaScript-Array-Einfügemethode im Stil von:
arr.insert(index, item)
Am besten in jQuery, aber jede JavaScript-Implementierung reicht an dieser Stelle aus.
javascript
jquery
arrays
tags2k
quelle
quelle
Antworten:
Was Sie wollen, ist die
splice
Funktion für das native Array-Objekt.arr.splice(index, 0, item);
einfügen wirditem
inarr
am angegebenen Index (Löschen0
Artikel zuerst, das heißt, es ist nur ein Einsatz).In diesem Beispiel erstellen wir ein Array und fügen ihm ein Element in Index 2 hinzu:
quelle
arr.splice(2,3)
Entfernt 3 Elemente ab Index 2. Ohne Übergabe des 3. .... N-ten Parameters wird nichts eingefügt. Der Name wird deminsert()
also auch nicht gerecht.Sie können die
Array.insert
Methode folgendermaßen implementieren :Dann können Sie es wie folgt verwenden:
quelle
Array.prototype.insert = function (index, items) { this.splice.apply(this, [index, 0].concat(items)); }
Anders als beim Spleißen können Sie diesen Ansatz verwenden, bei dem das ursprüngliche Array nicht mutiert wird, sondern ein neues Array mit dem hinzugefügten Element erstellt wird. Sie sollten Mutationen nach Möglichkeit vermeiden, wann immer dies möglich ist. Ich verwende hier den ES6-Spread-Operator.
Dies kann verwendet werden, um mehr als ein Element hinzuzufügen, indem Sie die Funktion ein wenig optimieren, um den Restoperator für die neuen Elemente zu verwenden, und dies auch im zurückgegebenen Ergebnis verteilen
quelle
Benutzerdefinierte Array-
insert
Methoden1. Mit mehreren Argumenten und Verkettungsunterstützung
Es kann mehrere Elemente einfügen (wie es native
splice
tut) und unterstützt die Verkettung:2. Unterstützung beim Zusammenführen und Verketten von Argumenten vom Typ Array
Es kann Arrays aus den Argumenten mit dem angegebenen Array zusammenführen und unterstützt auch die Verkettung:
DEMO: http://jsfiddle.net/UPphH/
quelle
["b", "X", "Y", "Z", "c"]
. Warum ist nicht"d"
enthalten? Es scheint mir, dass Sieslice()
alle 6 Elemente im Rückgabewert erhalten sollten , wenn Sie 6 als zweiten Parameter von und 6 Elemente im Array beginnend mit dem angegebenen Index angeben. (Das Dokument sagthowMany
für diesen Parameter.) Developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…["a", "b", "c", "d"].insert(2, "X", "Y", "Z").slice(3, 3);
=>[ ]
slice
Methode verwendet und nichtsplice
, auf die Sie sich im Kommentar beziehen. Der zweite Parameter vonslice
(benanntend
) ist ein auf Null basierender Index, bei dem die Extraktion beendet werden soll.slice
Auszüge bis zu, aber nicht einschließlichend
. Daher, nachdeminsert
Sie haben["a", "b", "X", "Y", "Z", "c", "d"]
, aus denenslice
Elemente mit Indizes von1
bis extrahiert werden6
, dh von"b"
bis,"d"
aber nicht einschließlich"d"
. Macht das Sinn?Wenn Sie mehrere Elemente gleichzeitig in ein Array einfügen möchten, lesen Sie diese Antwort zum Stapelüberlauf: Eine bessere Möglichkeit, ein Array in Javascript in ein Array zu verbinden
Auch hier sind einige Funktionen, um beide Beispiele zu veranschaulichen:
Schließlich ist hier eine jsFiddle, damit Sie sie selbst sehen können: http://jsfiddle.net/luisperezphd/Wc8aS/
Und so nutzen Sie die Funktionen:
quelle
Für eine ordnungsgemäße funktionale Programmierung und Verkettung ist eine Erfindung von
Array.prototype.insert()
wesentlich. Tatsächlich hätte der Spleiß perfekt sein können, wenn er das mutierte Array anstelle eines völlig bedeutungslosen leeren Arrays zurückgegeben hätte. Also los geht'sNun gut, das obige mit dem
Array.prototype.splice()
einen mutiert das ursprüngliche Array und einige könnten sich beschweren wie "Sie sollten nicht ändern, was Ihnen nicht gehört" und das könnte sich auch als richtig herausstellen. Für das Gemeinwohl möchte ich eine andere geben,Array.prototype.insert()
die das ursprüngliche Array nicht mutiert. Hier kommt's;quelle
splice
das ursprüngliche Array mutieren, glaube ich nicht, dass "ordnungsgemäße funktionale Programmierung" irgendwo in die Nähe von gehörtsplice
.Ich empfehle in diesem Fall die Verwendung von reinem JavaScript. Es gibt auch keine Einfügemethode in JavaScript, aber wir haben eine Methode, die eine integrierte Array- Methode ist, die die Arbeit für Sie erledigt. Sie heißt Spleiß ...
Mal sehen, was splice () ist ...
OK, stellen Sie sich vor, wir haben dieses Array unten:
Wir können so entfernen
3
:Es wird 3 zurückgeben, aber wenn wir die Arr jetzt überprüfen, haben wir:
So weit, so gut, aber wie können wir dem Array mit Splice ein neues Element hinzufügen? Lassen Sie uns 3 in der arr ...
Mal sehen, was wir getan haben ...
Wir verwenden wieder Spleiß , aber dieses Mal übergeben wir für das zweite Argument 0 , was bedeutet, dass wir kein Element löschen möchten, aber gleichzeitig fügen wir das dritte Argument hinzu, nämlich 3, das beim zweiten Index hinzugefügt wird ...
Sie sollten sich bewusst sein, dass wir gleichzeitig löschen und hinzufügen können. Zum Beispiel können wir jetzt Folgendes tun:
Dadurch werden 2 Elemente bei Index 2 gelöscht , dann 3 bei Index 2 hinzugefügt und das Ergebnis lautet:
Dies zeigt, wie jedes Element im Spleiß funktioniert:
quelle
Fügen Sie ein einzelnes Element an einen bestimmten Index an
Hängen Sie mehrere Elemente an einen bestimmten Index an
quelle
arrName[3] = 'newName1';
wird angehängt , wenn das Array nur 3 Elemente enthält. Wenn Index 3 ein Element enthält, wird dieses ersetzt. Wenn Sie am Ende anhängen möchten, ist es besser zu verwendenarrName.push('newName1');
Eine andere mögliche Lösung mit der Verwendung von
Array#reduce
.quelle
Hier sind zwei Möglichkeiten:
ODER
quelle
Obwohl dies bereits beantwortet wurde, füge ich diesen Hinweis für einen alternativen Ansatz hinzu.
Ich wollte eine bekannte Anzahl von Elementen in einem Array an bestimmten Positionen platzieren, da sie aus einem "assoziativen Array" (dh einem Objekt) stammen, das per Definition nicht garantiert in einer sortierten Reihenfolge vorliegt. Ich wollte, dass das resultierende Array ein Array von Objekten ist, aber die Objekte sollten sich in einer bestimmten Reihenfolge im Array befinden, da ein Array ihre Reihenfolge garantiert. Also habe ich das gemacht.
Zuerst das Quellobjekt, eine aus PostgreSQL abgerufene JSONB-Zeichenfolge. Ich wollte, dass es in jedem untergeordneten Objekt nach der Eigenschaft "order" sortiert wird.
Da die Anzahl der Knoten im Objekt bekannt ist, erstelle ich zunächst ein Array mit der angegebenen Länge:
Anschließend iterieren Sie das Objekt und platzieren die neu erstellten temporären Objekte an den gewünschten Stellen im Array, ohne dass wirklich "sortiert" wird.
quelle
Jeder, der immer noch Probleme mit diesem hat und alle oben genannten Optionen ausprobiert hat und es nie bekommen hat. Ich teile meine Lösung, um zu berücksichtigen, dass Sie die Eigenschaften Ihres Objekts gegenüber dem Array nicht explizit angeben möchten.
Dies ist eine Kombination aus Iteration des Referenzarrays und Vergleich mit dem Objekt, das Sie überprüfen möchten. Konvertieren Sie beide in eine Zeichenfolge und iterieren Sie sie, wenn sie übereinstimmt. Dann können Sie einfach zählen. Dies kann verbessert werden, aber hier habe ich mich niedergelassen. Hoffe das hilft.
quelle
Profitieren Sie von der Reduktionsmethode wie folgt:
Auf diese Weise können wir ein neues Array zurückgeben (dies ist eine coole funktionale Methode - viel besser als Push oder Splice), wobei das Element am Index eingefügt wird. Wenn der Index größer als die Länge des Arrays ist, wird es eingefügt Am Ende.
quelle
Array#splice()
ist der richtige Weg, es sei denn, Sie möchten wirklich vermeiden, dass das Array mutiert. Gegeben zwei Arraysarr1
undarr2
hier, wie Sie den Inhalt einfügen würdenarr2
inarr1
nach dem ersten Elemente:Wenn Sie Bedenken haben, das Array zu mutieren (z. B. wenn Sie Immutable.js verwenden), können Sie stattdessen verwenden
slice()
, nicht zu verwechselnsplice()
mit a'p'
.quelle
Ich habe es versucht und es funktioniert gut!
Index ist die Position, an der Sie das Element einfügen oder löschen möchten. 0 dh der zweite Parameter definiert die Anzahl der Elemente aus dem zu entfernenden Indexelement. Dies sind die neuen Einträge, die Sie im Array vornehmen möchten. Es kann einer oder mehrere sein.
quelle
Hier ist eine Arbeitsfunktion, die ich in einer meiner Anwendungen verwende.
Dies prüft, ob das Element beendet wird
Und dann nenne ich es unten.
quelle
Ein bisschen wie ein älterer Thread, aber ich muss Redu oben zustimmen, da Splice definitiv eine etwas verwirrende Oberfläche hat. Und die Antwort von cdbajorin, dass "ein leeres Array nur zurückgegeben wird, wenn der zweite Parameter 0 ist. Wenn es größer als 0 ist, werden die aus dem Array entfernten Elemente zurückgegeben", beweist dies den Punkt, obwohl es genau ist. Die Absicht der Funktion ist es, zu verbinden oder, wie bereits von Jakob Keller gesagt, "zu verbinden oder zu verbinden, auch zu ändern. Sie haben ein etabliertes Array, das Sie jetzt ändern, was das Hinzufügen oder Entfernen von Elementen beinhalten würde ..." Der Rückgabewert der Elemente, falls vorhanden, die entfernt wurden, ist bestenfalls umständlich. Und ich stimme zu 100% zu, dass diese Methode besser zur Verkettung geeignet gewesen wäre, wenn sie das zurückgegeben hätte, was natürlich erscheint, ein neues Array mit den hinzugefügten gespleißten Elementen. Dann könnten Sie Dinge wie ["19", "17"]. Splice (1,0, "18"). Join ("...") oder was auch immer Sie mit dem zurückgegebenen Array mögen. Die Tatsache, dass es zurückgibt, was entfernt wurde, ist meiner Meinung nach nur ein Unsinn. Wenn die Absicht der Methode darin bestand, "eine Reihe von Elementen auszuschneiden", und das war vielleicht nur die Absicht. Es scheint, als ob ich, wenn ich nicht weiß, was ich bereits ausschneide, wahrscheinlich wenig Grund habe, diese Elemente auszuschneiden, nicht wahr? Es wäre besser, wenn es sich wie Concat, Map, Reduce, Slice usw. verhalten würde, wenn ein neues Array aus dem vorhandenen Array erstellt wird, anstatt das vorhandene Array zu mutieren. Diese sind alle verkettbar, und das ist ein wichtiges Problem. Es ist ziemlich üblich, Array-Manipulationen zu verketten. Es scheint, als müsste die Sprache in die eine oder andere Richtung gehen und versuchen, so weit wie möglich daran festzuhalten. Da Javascript funktional und weniger aussagekräftig ist, scheint es nur eine seltsame Abweichung von der Norm zu sein.
quelle
Performance
Heute (2020.04.24) führe ich Tests für ausgewählte Lösungen für große und kleine Arrays durch. Ich habe sie auf MacOs High Sierra 10.13.6 auf Chrome 81.0, Safari 13.1, Firefox 75.0 getestet.
Schlussfolgerungen
Für alle Browser
slice
undreduce
(D, E, F) basieren, normalerweise 10x-100x schneller als in-place-Lösungensplice
(AI, BI, CI) basierenden In-Place-Lösungen am schnellsten (manchmal ~ 100x - dies hängt jedoch von der Arraygröße ab).Einzelheiten
Die Tests wurden in zwei Gruppen unterteilt: In-Place-Lösungen (AI, BI, CI) und Nicht-In-Place-Lösungen (D, E, F) und wurden für zwei Fälle durchgeführt
Der getestete Code ist im folgenden Snippet dargestellt
Code-Snippet anzeigen
Beispielergebnisse für kleine Arrays auf Chrom sind unten aufgeführt
quelle