Si j'ai un tableau de chaînes, je peux utiliser la .join()
méthode pour obtenir une seule chaîne, avec chaque élément séparé par des virgules, comme ceci:
["Joe", "Kevin", "Peter"].join(", ") // => "Joe, Kevin, Peter"
J'ai un tableau d'objets et j'aimerais effectuer une opération similaire sur une valeur contenue en son sein; donc de
[
{name: "Joe", age: 22},
{name: "Kevin", age: 24},
{name: "Peter", age: 21}
]
effectuer la join
méthode uniquement sur l' name
attribut, pour obtenir la même sortie qu'auparavant.
Actuellement, j'ai la fonction suivante:
function joinObj(a, attr){
var out = [];
for (var i = 0; i < a.length; i++){
out.push(a[i][attr]);
}
return out.join(", ");
}
Il n'y a rien de mal à ce code, cela fonctionne, mais tout d'un coup, je suis passé d'une ligne de code simple et succincte à une fonction très impérative. Existe-t-il une manière plus succincte, idéalement plus fonctionnelle, d'écrire cela?
javascript
arrays
object
jackweirdy
la source
la source
" ,".join([i.name for i in a])
users.map(x => x.name).join(', ');
.Réponses:
Si vous souhaitez mapper des objets à quelque chose (dans ce cas, une propriété). Je pense que
Array.prototype.map
c'est ce que vous recherchez si vous voulez coder de manière fonctionnelle.En JavaScript moderne:
(violon)
Si vous souhaitez prendre en charge des navigateurs plus anciens, qui ne sont pas conformes à ES5, vous pouvez le caler (il y a un polyfill sur la page MDN ci-dessus). Une autre alternative serait d'utiliser la
pluck
méthode underscorejs :la source
[x.name for x of users]
(spec wiki.ecmascript.org/doku.php?id=harmony:array_comprehensions ). Il convient de mentionner que, tout comme l'utilisation de map / réduire / filtre n'est pas très «pythonique», l'autre sens est probablement valable en JavaScript. CoffeeScript est cool avec eux via coffeescript.org .users.map((obj) -> obj.name).join(', ')
Eh bien, vous pouvez toujours remplacer la
toString
méthode de vos objets:la source
toString
méthode de tous les éléments, en utilisant une boucle for. Ou vous pouvez utiliser cette approche lorsque vous traitez avec des fonctions de constructeur, en ajoutant unetoString
méthode à laprototype
propriété du constructeur. Cet exemple était cependant censé montrer le concept de base.Je suis également tombé sur l'utilisation de la
reduce
méthode, voici à quoi cela ressemble:Le
(a.name || a)
est donc le premier élément est traité correctement, mais le reste (oùa
est une chaîne, et donca.name
n'est pas défini) n'est pas traité comme un objet.Edit: je l'ai maintenant refactorisé à la suite de ceci:
qui, je crois, est plus propre, comme
a
c'est toujours une chaîne,b
est toujours un objet (en raison de l'utilisation du paramètre optionnel initialValue dansreduce
)Edit 6 mois plus tard: Oh à quoi je pensais. "nettoyeur". J'ai mis en colère le code des dieux.
la source
reduce
n'est pas aussi largement pris en charge quemap
(ce qui est bizarre, étant donné que ce sont des sœurs), donc j'utilise toujours votre réponse :)Je ne sais pas s'il y a un moyen plus facile de le faire sans utiliser une bibliothèque externe, mais personnellement , je l' aime underscore.js qui a des tonnes de services publics pour faire face à des tableaux, collections , etc.
Avec le soulignement, vous pouvez le faire facilement avec une seule ligne de code:
_.pluck(arr, 'name').join(', ')
la source
arr
est votre tableau, naturellement)Sur le nœud ou ES6 +:
la source
disons que le tableau d'objets est référencé par la variable
users
Si ES6 peut être utilisé, la solution la plus simple sera:
Sinon, le lodash peut être utilisé de la manière suivante:
la source
Si objet et clés dynamiques:
"applications\":{\"1\":\"Element1\",\"2\":\"Element2\"}
la source
Un vieux fil que je connais mais toujours super pertinent pour tous ceux qui rencontrent cela.
Array.map a été suggéré ici, ce qui est une méthode géniale que j'utilise tout le temps. Array.reduce a également été mentionné ...
J'utiliserais personnellement un Array.reduce pour ce cas d'utilisation. Pourquoi? Malgré le code légèrement moins clair / clair. C'est beaucoup plus efficace que de diriger la fonction map vers une jointure.
La raison en est que Array.map doit faire une boucle sur chaque élément pour renvoyer un nouveau tableau avec tous les noms de l'objet dans le tableau. Array.join boucle ensuite sur le contenu du tableau pour effectuer la jointure.
Vous pouvez améliorer la lisibilité des jackweirdys réduire la réponse en utilisant des littéraux de modèle pour obtenir le code sur une seule ligne. "Pris en charge dans tous les navigateurs modernes aussi"
la source
Je ne sais pas, mais tout cela répond qu'ils fonctionnent mais ne sont pas optiomaux car ils effectuent deux analyses et vous pouvez effectuer cela en une seule analyse. Même si O (2n) est considéré comme O (n), il est toujours préférable d'avoir un vrai O (n).
Cela pourrait ressembler à de la vieille école, mais cela me permet de faire ça comme ceci:
la source
essaye ça
la source
name
attribut. (a[i].name
n'utilise pas l'name
argument de votre fonction , il est équivalent àa[i]['name']
.)