Ich wollte allen Objekten in einem Array einen key:value-Parameter hinzufügen.
z.B:
var arrOfObj = [{name: 'eve'},{name:'john'},{name:'jane'}];
Jetzt wollte ich allen Objekten einen neuen Parameter hinzufügen, isActive, damit das resultierende Array so aussieht.
z.B:
[{
name: 'eve',
isActive: true
}, {
name: 'john',
isActive: true
}, {
name: 'jane',
isActive: true
}]
Ich kann das Array immer durchlaufen und ein Schlüssel-Wert-Paar einfügen. Aber ich frage mich, ob es einen besseren Weg gibt, dies zu tun
Das Karte() Funktion ist die beste Wahl für diesen Fall
tl;dr – Tun Sie dies:
const newArr = [
{name: 'eve'},
{name: 'john'},
{name: 'jane'}
].map(v => ({...v, isActive: true}))
Das Karte() Funktion wird nicht ändern das anfängliche Array, sondern erstellt ein neues. Dies ist auch eine gute Vorgehensweise, um das anfängliche Array unverändert zu lassen.
Alternativen:
const initialArr = [
{name: 'eve'},
{name: 'john'},
{name: 'jane'}
]
const newArr1 = initialArr.map(v => ({...v, isActive: true}))
const newArr2 = initialArr.map(v => Object.assign(v, {isActive: true}))
// Results of newArr1 and newArr2 are the same
Fügen Sie ein Schlüsselwertpaar hinzu bedingt
const arr = [{value: 1}, {value: 1}, {value: 2}]
const newArr1 = arr.map(v => ({...v, isActive: v.value > 1}))
Was ist, wenn ich überhaupt kein neues Feld hinzufügen möchte, wenn die Bedingung falsch ist?
const arr = [{value: 1}, {value: 1}, {value: 2}]
const newArr = arr.map(v => {
return v.value > 1 ? {...v, isActive: true} : v
})
Hinzufügen MIT Änderung des ursprünglichen Arrays
const initialArr = [{a: 1}, {b: 2}]
initialArr.forEach(v => {v.isActive = true;});
Das ist wahrscheinlich keine gute Idee, aber im wirklichen Leben ist es manchmal der einzige Weg.
Fragen
- Soll ich einen Spread-Operator verwenden (
...
), oder Object.assign
und was ist der unterschied?
Persönlich bevorzuge ich den Spread-Operator, weil ich denke, dass er in der modernen Web-Community viel häufiger verwendet wird (insbesondere die Entwickler von React lieben ihn). Aber Sie können den Unterschied selbst überprüfen: Link (etwas eigensinnig und alt, aber immer noch)
- Kann ich benutzen
function
Stichwort statt =>
?
Sicher kannst du. Der dicke Pfeil (=>
) Funktionen spielen ein bisschen anders mit this
, aber es ist für diesen speziellen Fall nicht so wichtig. Fette Pfeile funktionieren jedoch kürzer und spielen sich manchmal besser als Callbacks. Daher ist die Verwendung von Fettpfeilfunktionen ein modernerer Ansatz.
- Was passiert tatsächlich innerhalb der Kartenfunktion:
.map(v => ({...v, isActive: true})
?
Die Map-Funktion iteriert durch die Elemente des Arrays und wendet die Callback-Funktion für jedes von ihnen an. Diese Rückruffunktion sollte etwas zurückgeben, das zu einem Element eines neuen Arrays wird. Wir sagen dem .map()
folgende Funktion: Aktuellen Wert nehmen (v
was ein Objekt ist), nimm alle Schlüssel-Wert-Paare weg von v
und lege es in ein neues Objekt ({...v}
), sondern auch Eigenschaft hinzufügen isActive
und setze es auf wahr ({...v, isActive: true}
) und dann das Ergebnis zurückgeben. Btw, wenn Originalobjekt enthalten ist isActive
abgelegt, wird es überschrieben. Object.assign
funktioniert ähnlich.
- Kann ich mehr als ein Feld gleichzeitig hinzufügen
Ja.
[{value: 1}, {value: 1}, {value: 2}].map(v => ({...v, isActive: true, howAreYou: 'good'}))
- Was ich drinnen nicht machen sollte
.map()
Methode
Sie sollten keine Nebenwirkungen haben[link 1, link 2]aber anscheinend können Sie.
Das merkt man auch map()
iteriert über jedes Element des Arrays und wendet die Funktion auf jedes von ihnen an. Wenn Sie also drinnen schwere Sachen machen, könnten Sie langsam sein. Diese (etwas hacky) Lösung könnte in einigen Fällen produktiver sein (aber ich denke nicht, dass Sie sie mehr als einmal im Leben anwenden sollten).
- Kann ich den Rückruf der Karte in eine separate Funktion extrahieren?
Sicher kannst du.
const arr = [{value: 1}, {value: 1}, {value: 2}]
const newArr = arr.map(addIsActive)
function addIsActive(v) {
return {...v, isActive: true}
}
- Was ist falsch an der alten guten for-Schleife?
Nichts ist falsch mit for
, können Sie es immer noch verwenden, es ist nur ein Ansatz der alten Schule, der ausführlicher und weniger sicher ist und das ursprüngliche Array mutiert. Aber du kannst es versuchen:
const arr = [{a: 1}, {b: 2}]
for (let i = 0; i < arr.length; i++) {
arr[i].isActive = true
}
- Was ich auch lernen sollte
Es wäre klug, die folgenden Methoden gut zu lernen Karte(), Filter(), reduzieren(), für jeden()und finden(). Diese Methoden können 80 % dessen lösen, was Sie normalerweise mit Arrays tun möchten.
Sie können dies mit tun map()
var arrOfObj = [{
name: 'eve'
}, {
name: 'john'
}, {
name: 'jane'
}];
var result = arrOfObj.map(function(o) {
o.isActive = true;
return o;
})
console.log(result)
Wenn Sie das ursprüngliche Array beibehalten möchten, können Sie Objekte mit klonen Object.assign()
var arrOfObj = [{
name: 'eve'
}, {
name: 'john'
}, {
name: 'jane'
}];
var result = arrOfObj.map(function(el) {
var o = Object.assign({}, el);
o.isActive = true;
return o;
})
console.log(arrOfObj);
console.log(result);
Ich wäre mit einigen der hier vorgestellten Antworten etwas vorsichtig, die folgenden Beispiele geben je nach Ansatz unterschiedliche Ergebnisse aus:
const list = [ { a : 'a', b : 'b' } , { a : 'a2' , b : 'b2' }]
console.log(list.map(item => item.c="c"))
// [ 'c', 'c' ]
console.log(list.map(item => {item.c="c"; return item;}))
// [ { a: 'a', b: 'b', c: 'c' }, { a: 'a2', b: 'b2', c: 'c' } ]
console.log(list.map(item => Object.assign({}, item, { c : 'c'})))
// [ { a: 'a', b: 'b', c: 'c' }, { a: 'a2', b: 'b2', c: 'c' } ]
Ich habe benutzt Knoten v8.10.0 um die obigen Codeteile zu testen.
Sie können auch Folgendes versuchen:
arrOfObj.forEach(function(item){item.isActive = true;});
console.log(arrOfObj);
Die Lösung von @Redu ist eine gute Lösung
arrOfObj.map(o => o.isActive = true;), aber Array.map zählt immer noch als Schleife durch alle Elemente.
Wenn Sie absolut keine Schleifen haben möchten, ist hier ein schmutziger Hack:
Object.defineProperty(Object.prototype, "isActive",{
value: true,
writable: true,
configurable: true,
enumerable: true
});
Mein Rat ist jedoch, es nicht sorgfältig zu verwenden, es wird absolut alle Javascript-Objekte (Date, Array, Number, String oder andere, die Object erben) patchen, was wirklich eine schlechte Praxis ist …
arrOfObj.map(o => {
o.isActive = true;
return o;
});
_.forEach(arrOfObj,(arrVal,arrIn) => {
arrVal.isAcitve = true;
}
arrOfObj.map(o => o.isActive = true;)
– Redu
3. Oktober 2016 um 8:15 Uhr
besser wäre arrOfObj.map(o => (o.isActive = true)); Dies würde keinen No-Return-Assign-Fehler auf ESLint auslösen und wird auch als Best Practice angesehen.
– Sara Arya
13. Juli 2017 um 6:42 Uhr