J'ai un tableau d'objets JavaScript avec la structure suivante:
objArray = [ { foo: 1, bar: 2}, { foo: 3, bar: 4}, { foo: 5, bar: 6} ];
Je veux extraire un champ de chaque objet et obtenir un tableau contenant les valeurs, par exemple un champ foo
donnerait un tableau[ 1, 3, 5 ]
.
Je peux le faire avec cette approche triviale:
function getFields(input, field) {
var output = [];
for (var i=0; i < input.length ; ++i)
output.push(input[i][field]);
return output;
}
var result = getFields(objArray, "foo"); // returns [ 1, 3, 5 ]
Existe-t-il une manière plus élégante ou idiomatique de le faire, de sorte qu'une fonction utilitaire personnalisée ne serait pas nécessaire?
Remarque sur les doublons suggérés , il explique comment convertir un seul objet en tableau.
var foos = objArray.pluck("foo");
.Array.prototype.map
fonction native là où elle existeRéponses:
Voici un moyen plus court d'y parvenir:
OU
Vous pouvez également vérifier
Array.prototype.map()
.la source
Oui, mais il repose sur une fonctionnalité ES5 de JavaScript. Cela signifie qu'il ne fonctionnera pas dans IE8 ou une version antérieure.
Sur les interprètes JS compatibles ES6, vous pouvez utiliser une fonction de flèche pour plus de brièveté:
Documentation Array.prototype.map
la source
foo
?var result = objArray.map((a) => (a.foo));
var result = objArray.map(a => a.foo);
Découvrez la
_.pluck()
fonction de Lodash ou la fonction Underscore_.pluck()
. Les deux font exactement ce que vous voulez en un seul appel de fonction!Mise à jour:
_.pluck()
a été supprimée à partir de Lodash v4.0.0 , en faveur de_.map()
en combinaison avec quelque chose de similaire à la réponse de Niet ._.pluck()
est toujours disponible dans Underscore .Mise à jour 2: Comme Mark le souligne dans les commentaires , quelque part entre Lodash v4 et 4.3, une nouvelle fonction a été ajoutée qui fournit à nouveau cette fonctionnalité.
_.property()
est une fonction abrégée qui renvoie une fonction pour obtenir la valeur d'une propriété dans un objet.En outre,
_.map()
permet désormais de passer une chaîne en tant que deuxième paramètre, qui est passé dans_.property()
. Par conséquent, les deux lignes suivantes sont équivalentes à l'exemple de code ci-dessus de pré-Lodash 4._.property()
, et donc_.map()
, vous permet également de fournir une chaîne ou un tableau séparé par des points afin d'accéder aux sous-propriétés:Les deux
_.map()
appels dans l'exemple ci-dessus seront renvoyés[5, 2, 9]
.Si vous êtes un peu plus dans la programmation fonctionnelle, jetez un œil à la
R.pluck()
fonction de Ramda , qui ressemblerait à quelque chose comme ceci:la source
_.property('foo')
( lodash.com/docs#property ) a été ajouté comme raccourci pourfunction(o) { return o.foo; }
. Cela raccourcit le cas d'utilisation de Lodash àvar result = _.pluck(objArray, _.property('foo'));
Pour plus de commodité, la_.map()
méthode de Lodash 4.3.0 permet également une utilisation sténographique_.property()
sous le capot, ce qui entraînevar result = _.map(objArray, 'foo');
En parlant des solutions JS uniquement, j'ai trouvé que, aussi élégante soit-elle, une simple
for
boucle indexée est plus performante que ses alternatives.Extraction d'une propriété unique à partir d'un tableau d'éléments 100000 (via jsPerf)
Traditionnel pour boucle 368 Ops / sec
ES6 pour..de boucle 303 Ops / sec
Array.prototype.map 19 Ops / sec
TL; DR - .map () est lent, mais n'hésitez pas à l'utiliser si vous pensez que la lisibilité vaut plus que les performances.
Edit # 2: 6/2019 - Lien jsPerf cassé, supprimé.
la source
Il est préférable d'utiliser une sorte de bibliothèque comme lodash ou underscore pour une assurance multi-navigateur.
Dans Lodash, vous pouvez obtenir les valeurs d'une propriété dans un tableau en suivant la méthode
et dans Underscore
Les deux reviendront
la source
En utilisant
Array.prototype.map
:Voir le lien ci-dessus pour une cale pour les navigateurs pré-ES5.
la source
Dans ES6, vous pouvez faire:
la source
Bien
map
qu'il s'agisse d'une bonne solution pour sélectionner des «colonnes» dans une liste d'objets, elle présente un inconvénient. S'il n'est pas explicitement vérifié si les colonnes existent ou non, cela générera une erreur et (au mieux) vous fourniraundefined
. J'opterais pour unereduce
solution, qui peut simplement ignorer la propriété ou même vous définir une valeur par défaut.exemple jsbin
Cela fonctionnerait même si l'un des éléments de la liste fournie n'est pas un objet ou ne contient pas le champ.
Il peut même être rendu plus flexible en négociant une valeur par défaut si un élément n'est pas un objet ou ne contient pas le champ.
exemple jsbin
Ce serait la même chose avec la carte, car la longueur du tableau retourné serait la même que celle du tableau fourni. (Dans ce cas, a
map
est légèrement moins cher que areduce
):exemple jsbin
Et puis il y a la solution la plus flexible, celle qui vous permet de basculer entre les deux comportements simplement en fournissant une valeur alternative.
exemple jsbin
Comme les exemples ci-dessus (espérons-le) éclairent la façon dont cela fonctionne, permet de raccourcir un peu la
Array.concat
fonction en utilisant la fonction.exemple jsbin
la source
En général, si vous souhaitez extrapoler des valeurs d'objet qui sont à l'intérieur d'un tableau (comme décrit dans la question), vous pouvez utiliser la déstructuration de réduction, de mappage et de tableau.
ES6
L'équivalent utilisant for in loop serait:
Sortie produite: ["mot", "encore", "certains", "1", "2", "3"]
la source
Cela dépend de votre définition de «mieux».
Les autres réponses soulignent l'utilisation de la carte, qui est naturelle (surtout pour les gars habitués au style fonctionnel) et concise. Je recommande fortement de l'utiliser (si vous ne vous embêtez pas avec les quelques gars d'IE8-IT). Donc, si "mieux" signifie "plus concis", "maintenable", "compréhensible", alors oui, c'est bien mieux.
En revanche, cette beauté ne va pas sans coûts supplémentaires. Je ne suis pas un grand fan de microbench, mais j'ai mis un petit test ici . Les résultats sont prévisibles, l'ancienne méthode laide semble être plus rapide que la fonction de carte. Donc, si "mieux" signifie "plus vite", alors non, restez avec la vieille école.
Encore une fois, ce n'est qu'un microbench et en aucun cas contre l'utilisation de
map
, c'est juste mes deux cents :).la source
map
c'est la façon la plus évidente d'aller, d'une manière ou d'une autre, je n'ai tout simplement pas trouvé avec google (j'ai trouvé la carte de jquery, ce qui n'est pas pertinent).Si vous souhaitez également prendre en charge les objets de type tableau, utilisez Array.from ( ES2015 ):
L'avantage qu'il a sur la méthode Array.prototype.map () est que l'entrée peut également être un ensemble :
la source
Si vous voulez plusieurs valeurs dans ES6 +, ce qui suit fonctionnera
Cela fonctionne car
{foo, baz}
à gauche utilise la déstructuration d'objets et sur le côté droit de la flèche est équivalent en{foo: foo, baz: baz}
raison des littéraux d'objets améliorés d' ES6 .la source
La carte des fonctions est un bon choix pour les tableaux d'objets. Bien qu'un certain nombre de bonnes réponses aient déjà été publiées, l'exemple d'utilisation de la carte avec une combinaison avec un filtre peut être utile.
Si vous souhaitez exclure les propriétés dont les valeurs ne sont pas définies ou exclure uniquement une propriété spécifique, vous pouvez procéder comme suit:
https://jsfiddle.net/ohea7mgk/
la source
La réponse fournie ci-dessus est bonne pour extraire une seule propriété, que se passe-t-il si vous souhaitez extraire plusieurs propriétés d'un tableau d'objets. Voici la solution !! Dans ce cas, nous pouvons simplement utiliser _.pick (objet, [chemins])
Supposons que objArray possède des objets avec trois propriétés comme ci-dessous
Maintenant, nous voulons extraire la propriété foo et bar de chaque objet et les stocker dans un tableau séparé. Nous allons d'abord itérer les éléments du tableau à l'aide de la carte, puis nous y appliquerons la méthode Lodash Library Standard _.pick ().
Nous pouvons maintenant extraire les propriétés 'foo' et 'bar'.
var newArray = objArray.map((element)=>{ return _.pick(element, ['foo','bar'])}) console.log(newArray);
et le résultat serait [{foo: 1, bar: 2}, {foo: 3, bar: 4}, {foo: 5, bar: 6}]
prendre plaisir!!!
la source
_.pick
vient-il? Ce n'est pas une fonction standard.Si vous avez des tableaux imbriqués, vous pouvez le faire fonctionner comme ceci:
la source