Disons que j'ai un objet:
elmo = {
color: 'red',
annoying: true,
height: 'unknown',
meta: { one: '1', two: '2'}
};
Je veux créer un nouvel objet avec un sous-ensemble de ses propriétés.
// pseudo code
subset = elmo.slice('color', 'height')
//=> { color: 'red', height: 'unknown' }
Comment puis-je y parvenir?
javascript
Christian Schlensker
la source
la source
emo.slice
à première vue.Réponses:
Utilisation de la déstructuration d'objets et de la sténographie des propriétés
De Philipp Kewisch:
la source
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
, créerpicked
comme{ a: 5, c: 7 }
. Vous avez simplement spécifié de supprimer b. Votre eslint sera probablement agacé par vous pour avoir déclaré un var que vous n'utilisez pas.Je suggère de jeter un œil à Lodash ; il a beaucoup de grandes fonctions utilitaires.
Par exemple, ce
pick()
serait exactement ce que vous recherchez:violon
la source
_.omit(elmo, ['voice'])
pour tout retourner, maisvoice
Si vous utilisez ES6, il existe un moyen très concis de le faire en utilisant la déstructuration. La déstructuration vous permet d'ajouter facilement des objets à l'aide d'une répartition, mais elle vous permet également de créer des objets de sous-ensemble de la même manière.
la source
Bien qu'il soit un peu plus verbeux, vous pouvez accomplir ce que tout le monde recommandait le soulignement / lodash il y a 2 ans, en utilisant Array.prototype.reduce .
Cette approche le résout de l'autre côté: plutôt que de prendre un objet et de lui passer des noms de propriété à extraire, de prendre un tableau de noms de propriété et de les réduire en un nouvel objet.
Bien qu'il soit plus détaillé dans le cas le plus simple, un rappel ici est assez pratique, car vous pouvez facilement répondre à certaines exigences courantes, par exemple changer la propriété 'color' en 'color' sur le nouvel objet, aplatir les tableaux, etc. - n'importe lequel des les choses que vous devez faire lorsque vous recevez un objet d'un service / bibliothèque et que vous créez un nouvel objet nécessaire ailleurs. Bien que le soulignement / lodash soient d'excellentes bibliothèques bien implémentées, c'est mon approche préférée pour moins de dépendance vis-à-vis des fournisseurs, et une approche plus simple et plus cohérente lorsque ma logique de construction de sous-ensemble devient plus complexe.
edit: version es7 du même:
edit: Un bel exemple pour le curry, aussi! Avoir une fonction 'pick' renvoie une autre fonction.
Ce qui précède est assez proche de l'autre méthode, sauf qu'il vous permet de créer un «sélecteur» à la volée. par exemple
Ce qui est particulièrement intéressant avec cette approche, c'est que vous pouvez facilement passer les «choix» choisis dans tout ce qui prend une fonction, par exemple
Array#map
:la source
function showToy({ color, height }) {
ne mettrait que ce dont vous avez besoin dans la portée. L'reduce
approche est principalement logique lorsque vous simplifiez des objets pour la sérialisation.const pick = (obj, props) => props.reduce((a, e) => (a[e] = obj[e], a), {});
fetch
), donc je recommanderais d'ajouter un commentaire expliquant l'utilisation de l'opérateur virgule.Déstructuration ES6
La syntaxe de déstructuration permet de déstructurer et de recombiner un objet, avec des paramètres de fonction ou des variables.
La limitation est qu'une liste de clés est prédéfinie, elles ne peuvent pas être répertoriées comme des chaînes, comme le mentionne la question. La déstructuration devient plus compliquée si une clé n'est pas alphanumérique, par exemple
foo_bar
.L'inconvénient est que cela nécessite de dupliquer une liste de clés, ce qui entraîne un code détaillé au cas où une liste est longue. Étant donné que la déstructuration duplique la syntaxe littérale des objets dans ce cas, une liste peut être copiée et collée telle quelle.
L'avantage est que c'est une solution performante qui est naturelle pour ES6.
IIFE
Variables temporaires
Une liste de chaînes
La liste arbitraire des clés sélectionnées se compose de chaînes, comme l'exige la question. Cela permet de ne pas les prédéfinir et d'utiliser des variables qui contiennent des noms de clés, comme
pick(obj, 'foo', someKey, ...moreKeys)
.Une doublure devient plus courte avec chaque édition JS.
ES5
ES6
Ou avec un opérateur virgule:
ES2019
ECMAScript 2017 a
Object.entries
etArray.prototype.includes
, ECMAScript 2019 aObject.fromEntries
, ils peuvent être polyfilled en cas de besoin et rendre la tâche plus facile:Un one-liner peut être réécrit comme une fonction d'assistance similaire à Lodash
pick
ouomit
où la liste des clés est passée par des arguments:Une note sur les clés manquantes
La principale différence entre la déstructuration et la fonction conventionnelle de type Lodash
pick
est que la déstructuration inclut des clés choisies inexistantes avec uneundefined
valeur dans un sous-ensemble:Ce comportement peut être souhaitable ou non. Il ne peut pas être modifié pour la syntaxe de déstructuration.
Alors que
pick
peut être modifié pour inclure les clés manquantes en itérant une liste de clés sélectionnées à la place:la source
obj
variable soit une variable qui stocke un objet. Si le nom de votre variable diffère, utilisez-le à la place deobj
.Object.keys(obj)
. Somnolent.Il n'y a rien de tel que intégré à la bibliothèque principale, mais vous pouvez utiliser la déstructuration d'objets pour le faire ...
Vous pouvez également écrire une fonction utilitaire le faire ...
Des bibliothèques comme Lodash en ont également
_.pick()
.la source
J'ajoute cette réponse car aucune des réponses n'a été utilisée
Comma operator
.C'est très facile avec
destructuring assignment
et,
opérateurAvec une certaine amélioration pour l'attribution des propriétés dynamiques, cela pourrait ressembler à ceci:
la source
'use strict'
). Je reçois unReferenceError: a is not defined
.a
etc
- veillez à ne pas écraser au hasard les variables locales ou globales en fonction du contexte. (La réponse acceptée évite ce problème en utilisant deux variables locales dans une fonction en ligne, qui tombe hors de portée après exécution immédiate.)Encore une solution:
Cela me semble beaucoup plus lisible que n'importe quelle réponse jusqu'à présent, mais peut-être que c'est juste moi!
la source
subset = {color: elmo.color, height: elmo.color}
, j'aurais eu au moins un ... enfin, un centime peut-être.Vous pouvez également utiliser Lodash .
En complément, disons que vous avez un ensemble de "elmo":
Si vous voulez le même comportement, en utilisant lodash, vous devez simplement:
la source
La déstructuration en variables nommées dynamiquement est impossible en JavaScript comme discuté dans cette question .
Pour définir des clés de manière dynamique , vous pouvez utiliser la fonction de réduction sans mutation d'objet comme suit:
ci-dessous est une version utilisant réduire avec un seul clone (mise à jour de la valeur initiale transmise pour réduire).
la source
Solution TypeScript:
Les informations de saisie permettent même la saisie semi-automatique:
Crédit à DefinitelyTyped pour
U extends keyof T
astuce!la source
Utilisez la
pick
méthode de la bibliothèque lodash si vous l'utilisez déjà.https://lodash.com/docs/4.17.10#pick
la source
Solution dynamique
Afficher l'extrait de code
la source
Juste une autre façon ...
Vous pouvez utiliser cette fonction avec un tableau d'objets =)
la source
Que diriez-vous:
la source
false
(ou fausse). jsfiddle.net/nfAs8keys[i] in obj
.Cela fonctionne pour moi dans la console Chrome. Un problème avec ça?
la source
Affectation destructrice avec propriétés dynamiques
Cette solution s'applique non seulement à votre exemple spécifique mais est plus généralement applicable:
Vous pouvez facilement définir
subset4
etc. pour prendre en compte plus de propriétés.la source
Bon vieux
Array.prototype.reduce
:cette réponse utilise l'opérateur virgule magique, également: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator
si vous voulez devenir vraiment chic, c'est plus compact:
Tout rassembler dans une fonction réutilisable:
la source
convertir des arguments en tableau
utiliser
Array.forEach()
pour choisir la propriétéla source
la source
Essayer
la source
Ajoutant mes 2 cents à la réponse d' Ivan Nosov :
Dans mon cas, j'avais besoin de plusieurs clés pour être `` tranchées '' hors de l'objet, donc cela devient très très laid et pas une solution très dynamique:
Voici donc une solution dynamique utilisant eval:
la source
vous pouvez étendre jquery si vous le souhaitez, voici l'exemple de code pour une tranche:
voici le violon pour le même: http://jsfiddle.net/w633z/
la source