Angenommen, ich habe ein Objekt:
elmo = {
color: 'red',
annoying: true,
height: 'unknown',
meta: { one: '1', two: '2'}
};
Ich möchte ein neues Objekt mit einer Teilmenge seiner Eigenschaften erstellen.
// pseudo code
subset = elmo.slice('color', 'height')
//=> { color: 'red', height: 'unknown' }
Wie kann ich das erreichen?
javascript
Christian Schlensker
quelle
quelle
emo.slice
auf den ersten Blick.Antworten:
Verwenden von Objektzerstörung und Eigenschaftskürzel
Von Philipp Kewisch:
quelle
let unwrap = ({a, c}) => ({a, c}); let unwrap2 = function({a, c}) { return { a, c }; }; let picked = unwrap({ a: 5, b: 6, c: 7 });
const { b, ...picked } = object
schaffen würdepicked
wie{ a: 5, c: 7 }
. Sie haben angegeben, einfach zu entfernen b. Ihr Eslint wird Sie wahrscheinlich ärgern, wenn Sie eine Var deklarieren, die Sie nicht verwenden.Ich schlage vor, einen Blick auf Lodash zu werfen . Es hat viele großartige Utility-Funktionen.
Zum Beispiel
pick()
wäre genau das, was Sie suchen:Geige
quelle
_.omit(elmo, ['voice'])
, um alles außervoice
Wenn Sie ES6 verwenden, gibt es eine sehr präzise Möglichkeit, dies mithilfe der Destrukturierung zu tun. Durch die Destrukturierung können Sie Objekte mithilfe eines Spreads problemlos hinzufügen, aber auch Teilmengenobjekte auf die gleiche Weise erstellen.
quelle
Obwohl es etwas ausführlicher ist, können Sie mithilfe von Array.prototype.reduce das erreichen, was alle anderen vor 2 Jahren unterstrichen / lodash empfohlen haben .
Dieser Ansatz löst es von der anderen Seite: Anstatt ein Objekt zu nehmen und ihm Eigenschaftsnamen zum Extrahieren zu übergeben, nehmen Sie ein Array von Eigenschaftsnamen und reduzieren Sie sie in ein neues Objekt.
Während es im einfachsten Fall ausführlicher ist, ist ein Rückruf hier ziemlich praktisch, da Sie einige allgemeine Anforderungen leicht erfüllen können, z. B. die Eigenschaft 'color' für das neue Objekt in 'color' ändern, Arrays reduzieren usw. die Dinge, die Sie tun müssen, wenn Sie ein Objekt von einem Dienst / einer Bibliothek empfangen und ein neues Objekt erstellen, das an einem anderen Ort benötigt wird. Während Unterstriche / lodash ausgezeichnete, gut implementierte Bibliotheken sind, ist dies mein bevorzugter Ansatz für weniger Herstellerabhängigkeit und einen einfacheren, konsistenteren Ansatz, wenn meine Logik zum Erstellen von Teilmengen komplexer wird.
edit: es7 version desselben:
edit: Ein schönes Beispiel auch zum Curry! Lassen Sie eine 'Pick'-Funktion eine andere Funktion zurückgeben.
Das Obige kommt der anderen Methode ziemlich nahe, außer dass Sie damit im laufenden Betrieb einen "Picker" bauen können. z.B
Das Besondere an diesem Ansatz ist, dass Sie die ausgewählten "Picks" problemlos an alles übergeben können, was eine Funktion übernimmt, z
Array#map
.quelle
function showToy({ color, height }) {
würde nur das, was Sie brauchen, in den Geltungsbereich setzen. Derreduce
Ansatz ist hauptsächlich dann sinnvoll, wenn Sie Objekte für die Serialisierung vereinfachen.const pick = (obj, props) => props.reduce((a, e) => (a[e] = obj[e], a), {});
fetch
). Daher würde ich empfehlen, einen Kommentar hinzuzufügen, der die Verwendung des Komma-Operators erklärt.ES6-Destrukturierung
Die Destrukturierungssyntax ermöglicht das Destrukturieren und Rekombinieren eines Objekts mit Funktionsparametern oder Variablen.
Die Einschränkung besteht darin, dass eine Liste von Schlüsseln vordefiniert ist. Sie können nicht als Zeichenfolgen aufgeführt werden, wie in der Frage erwähnt. Die Destrukturierung wird komplizierter, wenn ein Schlüssel nicht alphanumerisch ist, z
foo_bar
.Der Nachteil ist, dass dies das Duplizieren einer Liste von Schlüsseln erfordert. Dies führt zu ausführlichem Code, falls eine Liste lang ist. Da die Destrukturierung in diesem Fall die Objektliteral-Syntax dupliziert, kann eine Liste unverändert kopiert und eingefügt werden.
Der Vorteil ist, dass es sich um eine performante Lösung handelt, die für ES6 selbstverständlich ist.
IIFE
Temporäre Variablen
Eine Liste von Zeichenfolgen
Die beliebige Liste der ausgewählten Schlüssel besteht je nach Frage aus Zeichenfolgen. Dies ermöglicht es, sie nicht vordefinieren und Variablen zu verwenden, die Schlüsselnamen enthalten, wie z
pick(obj, 'foo', someKey, ...moreKeys)
.Ein Einzeiler wird mit jeder JS-Ausgabe kürzer.
ES5
ES6
Oder mit Komma-Operator:
ES2019
ECMAScript 2017 hat
Object.entries
undArray.prototype.includes
ECMAScript 2019 hatObject.fromEntries
, sie können bei Bedarf polygefüllt werden und erleichtern die Aufgabe:Ein Einzeiler
pick
kann als Hilfsfunktion ähnlich wie Lodash umgeschrieben werden oderomit
wenn die Liste der Schlüssel über Argumente übergeben wird:Ein Hinweis zu fehlenden Schlüsseln
Der Hauptunterschied zwischen der Destrukturierung und der herkömmlichen Lodash-ähnlichen
pick
Funktion besteht darin, dass die Destrukturierung nicht vorhandene ausgewählte Schlüssel mit demundefined
Wert in einer Teilmenge enthält:Dieses Verhalten kann wünschenswert sein oder nicht. Es kann nicht für die Destrukturierungssyntax geändert werden.
Während
pick
kann geändert werden, um fehlende Schlüssel einzuschließen, indem stattdessen eine Liste der ausgewählten Schlüssel wiederholt wird:quelle
obj
Variable eine Variable ist, die ein Objekt speichert. Wenn sich Ihr Variablenname unterscheidet, verwenden Sie ihn anstelle vonobj
.Object.keys(obj)
. Schläfrig.In der Kernbibliothek ist nichts Vergleichbares integriert, aber Sie können die Objektzerstörung verwenden, um dies zu tun ...
Sie können auch ein Dienstprogramm schreiben, um es zu tun ...
Bibliotheken wie Lodash haben auch
_.pick()
.quelle
Ich füge diese Antwort hinzu, weil keine der Antworten verwendet wurde
Comma operator
.Es ist sehr einfach mit
destructuring assignment
und,
BedienerMit einer gewissen Verbesserung für die Zuweisung dynamischer Eigenschaften könnte dies folgendermaßen aussehen:
quelle
'use strict'
). Ich bekomme eineReferenceError: a is not defined
.a
undc
- achten Sie darauf, lokale oder globale Variablen je nach Kontext nicht zufällig zu überschreiben. (Die akzeptierte Antwort vermeidet dieses Problem, indem zwei lokale Variablen in einer Inline-Funktion verwendet werden, die nach sofortiger Ausführung nicht mehr in den Geltungsbereich fällt.)Noch eine Lösung:
Das sieht für mich weitaus lesbarer aus als so ziemlich jede Antwort bisher, aber vielleicht bin das nur ich!
quelle
subset = {color: elmo.color, height: elmo.color}
hätte, hätte ich mindestens einen ... na ja, vielleicht einen Cent gehabt.Sie können auch Lodash verwenden .
Nehmen wir an, Sie haben eine Reihe von "Elmos":
Wenn Sie dasselbe Verhalten mit lodash wünschen, würden Sie einfach:
quelle
Die Destrukturierung in dynamisch benannte Variablen ist in JavaScript nicht möglich, wie in dieser Frage erläutert .
Um Schlüssel dynamisch zu setzen , können Sie die Reduzierungsfunktion verwenden, ohne das Objekt wie folgt zu mutieren:
Im Folgenden finden Sie eine Version, bei der Reduzieren mit einem einzelnen Klon verwendet wird (Aktualisieren des zur Reduzierung übergebenen Anfangswertes).
quelle
TypeScript-Lösung:
Die Tippinformationen ermöglichen sogar die automatische Vervollständigung:
Dank an DefinitelyTyped für
U extends keyof T
Trick!quelle
Verwenden Sie die
pick
Methode der lodash-Bibliothek, wenn Sie sie bereits verwenden.https://lodash.com/docs/4.17.10#pick
quelle
Dynamische Lösung
Code-Snippet anzeigen
quelle
Nur ein anderer Weg ...
Sie können diese Funktion mit einem Array von Objekten verwenden =)
quelle
Wie wäre es mit:
quelle
false
(oder falsch) wäre. jsfiddle.net/nfAs8keys[i] in obj
.Dies funktioniert bei mir in der Chrome-Konsole. Irgendein Problem damit?
quelle
Destrukturierungszuordnung mit dynamischen Eigenschaften
Diese Lösung gilt nicht nur für Ihr spezifisches Beispiel, sondern ist allgemeiner anwendbar:
Sie können
subset4
usw. leicht definieren , um mehr Eigenschaften zu berücksichtigen.quelle
Gut alt
Array.prototype.reduce
:Diese Antwort verwendet den magischen Komma-Operator, außerdem: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator
Wenn Sie wirklich ausgefallen werden möchten, ist dies kompakter:
Alles zu einer wiederverwendbaren Funktion zusammenfügen:
quelle
Argumente in Array konvertieren
Verwenden Sie
Array.forEach()
, um die Eigenschaft auszuwählenquelle
quelle
Versuchen
quelle
Hinzufügen meiner 2 Cent zu Ivan Nosov Antwort:
In meinem Fall brauchte ich viele Schlüssel, um aus dem Objekt herausgeschnitten zu werden, damit es sehr schnell hässlich wird und keine sehr dynamische Lösung ist:
Hier ist also eine dynamische Lösung mit eval:
quelle
Sie können jquery erweitern, wenn Sie möchten. Hier ist der Beispielcode für ein Slice:
Hier ist die Geige dafür: http://jsfiddle.net/w633z/
quelle