J'ai un tableau d'objets que je veux parcourir pour produire un nouveau tableau filtré. Mais aussi, je dois filtrer certains des objets du nouveau tableau en fonction d'un paramètre. J'essaye ceci:
function renderOptions(options) {
return options.map(function (option) {
if (!option.assigned) {
return (someNewObject);
}
});
}
Est-ce une bonne approche? Existe-t-il une meilleure méthode? Je suis ouvert à utiliser n'importe quelle bibliothèque telle que lodash.
javascript
arrays
Daniel Calderon Mori
la source
la source
.reduce()
est définitivement plus rapide que de faire.filter(...).map(...)
ce que j'ai vu suggéré ailleurs. J'ai mis en place un test JSPerf pour démontrer stackoverflow.com/a/47877054/2379922Réponses:
Vous devriez utiliser
Array.reduce
pour cela.Alternativement, le réducteur peut être une fonction pure, comme ceci
la source
filtered
c'est un objet. c'est doncfiltered.push
indéfini pour moi.filtered
être un objet. C'était parce que je ne passais pas la "valeur initiale" - le tableau vide ([]
) après la fonction de réduction. par exemple incorrectvar reduced = options.reduce(function(filtered, option) { ... });
correctvar reduced = options.reduce(function(filtered, option) { ... }, []);
reduce
, vous pouvez tout aussi bien l'utiliserforEach
car à chaque itération vous changez de tableaufiltered
et donc ce n'est pas purement fonctionnel. Ce serait un événement plus lisible et compact.Utilisez réduire, Luke!
la source
Depuis 2019, Array.prototype.flatMap est une bonne option.
À partir de la page MDN liée ci-dessus:
la source
flatMap
été récemment introduit et que la prise en charge de son navigateur est limitée . Vous voudrez peut-être utiliser le polyfill / shims officiel: flatMap et flat .Avec ES6, vous pouvez le faire très brièvement:
options.filter(opt => !opt.assigned).map(opt => someNewObject)
la source
Une ligne
reduce
avec la syntaxe de propagation fantaisie ES6 est ici!la source
result
... est comme unefilter(assigned).map(name)
solution...assigned ? [name] : []
- c'est peut-être plus lisible que...(assigned ? [name] : [])
Je ferais un commentaire, mais je n'ai pas la réputation requise. Une petite amélioration à la très bonne réponse de Maxim Kuzmin pour la rendre plus efficace:
Explication
Au lieu de répartir le résultat entier encore et encore pour chaque itération, nous ajoutons uniquement au tableau, et uniquement lorsqu'il y a réellement une valeur à insérer.
la source
Utilisez Array.prototy.filter lui-même
la source
À un moment donné, n'est-il pas plus facile (ou tout aussi facile) d'utiliser un
forEach
Cependant, ce serait bien s'il y avait une fonction
malter()
oufap()
qui combine les fonctionsmap
etfilter
. Cela fonctionnerait comme un filtre, sauf qu'au lieu de renvoyer vrai ou faux, il renverrait n'importe quel objet ou un nul / non défini.la source
J'ai optimisé les réponses avec les points suivants:
if (cond) { stmt; }
commecond && stmt;
Je vais présenter deux solutions, l'une utilisant forEach , l'autre utilisant réduire :
Solution 1: utilisation de forEach
Solution 2: Utilisation de réduire
Je vous laisse le soin de décider de la solution à adopter.
la source
cond && stmt;
? Ceci est beaucoup plus difficile à lire et n'offre aucun avantage.En utilisant la réduction, vous pouvez le faire dans une fonction Array.prototype. Cela récupérera tous les nombres pairs d'un tableau.
Vous pouvez utiliser la même méthode et la généraliser pour vos objets, comme ceci.
arr
contiendra désormais les objets filtrés.la source
L'utilisation directe de
.reduce
peut être difficile à lire, je vous recommande donc de créer une fonction qui génère le réducteur pour vous:Utilisez-le comme ceci:
la source