Ich frage mich, ob es in lodash eine einfachere Methode gibt, um ein Element in einer JavaScript-Sammlung zu ersetzen. (Mögliches Duplikat, aber ich habe die Antwort dort nicht verstanden :)
Ich sah mir ihre Unterlagen an, konnte aber nichts finden
Mein Code lautet:
var arr = [{id: 1, name: "Person 1"}, {id:2, name:"Person 2"}];
// Can following code be reduced to something like _.XX(arr, {id:1}, {id:1, name: "New Name"});
_.each(arr, function(a, idx){
if(a.id === 1){
arr[idx] = {id:1, name: "Person New Name"};
return false;
}
});
_.each(arr, function(a){
document.write(a.name);
});
Update: Das Objekt, durch das ich ersetzen möchte, hat viele Eigenschaften wie
{id: 1, Prop1: ..., Prop2: ... und so weiter}
Lösung:
Dank dfsq habe ich aber in lodash eine richtige Lösung gefunden, die gut zu funktionieren scheint und ziemlich ordentlich ist, und ich habe sie auch in ein Mixin eingefügt, da ich diese Anforderung an vielen Stellen habe. JSBin
var update = function(arr, key, newval) {
var match = _.find(arr, key);
if(match)
_.merge(match, newval);
else
arr.push(newval);
};
_.mixin({ '$update': update });
var arr = [{id: 1, name: "Person 1"}, {id:2, name:"Person 2"}];
_.$update(arr, {id:1}, {id:1, name: "New Val"});
document.write(JSON.stringify(arr));
Schnellere Lösung Wie von @dfsq hervorgehoben, ist das Folgen viel schneller
var upsert = function (arr, key, newval) {
var match = _.find(arr, key);
if(match){
var index = _.indexOf(arr, _.find(arr, key));
arr.splice(index, 1, newval);
} else {
arr.push(newval);
}
};
javascript
lodash
Vishal Seth
quelle
quelle
_.findIndex
für Match verwenden._.findIndex
anstelle von_.find
sowohl die zweite_.find
als auch die zweite löschen_.indexOf
. Sie durchlaufen das Array dreimal, wenn Sie nur 1 benötigen.Antworten:
In Ihrem Fall müssen Sie lediglich das Objekt im Array finden und die
Array.prototype.splice()
Methode verwenden. Weitere Informationen finden Sie hier :quelle
indexOf
sie sehr schnell sein wird (es werden native Browser Array.prototype.indexOf verwendet). Trotzdem bin ich froh, dass Sie eine Lösung finden, die für Sie funktioniert._.findIndex
? Dann brauchen Sie nicht zu verwenden_.indexOf
.Die einfachste Lösung scheint die Verwendung von ES6
.map
oder lodash zu sein_.map
:Dies hat den schönen Effekt, dass das ursprüngliche Array nicht mutiert wird.
quelle
[ES6] Dieser Code funktioniert für mich.
quelle
updatedItem
wenn das Array kein Element mit demselben enthältid
.Testen wir nun die Leistung für alle Methoden:
Code-Snippet anzeigen
quelle
Sie können auch findIndex und pick verwenden, um das gleiche Ergebnis zu erzielen:
quelle
Im Laufe der Zeit sollten Sie einen funktionaleren Ansatz wählen, bei dem Sie Datenmutationen vermeiden und kleine Funktionen mit einer einzigen Verantwortung schreiben sollten. Mit dem ECMAScript 6 - Standard können Sie funktionales Programmierparadigma in JavaScript mit den nutzen
map
,filter
undreduce
Methoden. Sie brauchen keinen weiteren Lodash, Unterstrich oder was Sie sonst noch tun müssen, um die grundlegendsten Dinge zu tun.Unten habe ich einige Lösungsvorschläge für dieses Problem aufgeführt, um zu zeigen, wie dieses Problem mit verschiedenen Sprachfunktionen gelöst werden kann:
Verwenden der ES6-Karte:
Rekursive Version - entspricht der Zuordnung:
Erfordert Destrukturierung und Array-Verbreitung .
Wenn die Reihenfolge des endgültigen Arrays nicht wichtig ist, können Sie eine
object
als HashMap- Datenstruktur verwenden. Sehr praktisch, wenn Sie bereits eine Sammlung als Schlüssel eingegeben habenobject
- andernfalls müssen Sie zuerst Ihre Darstellung ändern.Erfordert die Verteilung von Objektresten , berechnete Eigenschaftsnamen und Object.entries .
quelle
Wenn Sie nur versuchen, eine Eigenschaft zu ersetzen, lodash
_.find
und_.set
sollte genug sein:quelle
Wenn die Einfügemarke des neuen Objekts nicht mit dem Index des vorherigen Objekts übereinstimmen muss, können Sie dies am einfachsten mit lodash tun,
_.reject
indem Sie neue Werte verwenden und dann in das Array verschieben:Wenn Sie mehrere Werte haben, die Sie in einem Durchgang ersetzen möchten, können Sie Folgendes tun (im Nicht-ES6-Format geschrieben):
quelle
Mit der Funktion lodash unionWith können Sie ein einfaches Upsert für ein Objekt durchführen. In der Dokumentation wird angegeben, dass bei einer Übereinstimmung das erste Array verwendet wird. Wickeln Sie Ihr aktualisiertes Objekt in [] (Array) und fügen Sie es als erstes Array der Vereinigungsfunktion ein. Geben Sie einfach Ihre übereinstimmende Logik an. Wenn sie gefunden wird, wird sie ersetzt und wenn nicht, wird sie hinzugefügt
Beispiel:
quelle
Keine schlechte Variante auch)
quelle
quelle
Wenn Sie nach einer Möglichkeit suchen, die Sammlung unveränderlich zu ändern (wie ich es war, als ich Ihre Frage gefunden habe), können Sie sich den Unveränderlichkeitshelfer ansehen , eine Bibliothek, die aus dem ursprünglichen React-Util stammt. In Ihrem Fall würden Sie das, was Sie erwähnt haben, über Folgendes erreichen:
quelle
Sie können es ohne lodash tun.
quelle
Unveränderlich , geeignet für
ReactJS
:Annehmen:
Das aktualisierte Element ist das zweite und der Name wird geändert in
Special Person
:Hinweis : Das Lodash hat nützliche Tools, aber jetzt haben wir einige davon in Ecmascript6 +, daher verwende ich nur
map
Funktionen, die sowohl fürlodash
als auch fürecmascript6+
:quelle
Kam auch darüber hinweg und tat es einfach so.
Wenn gewünscht, können wir es verallgemeinern
quelle