Mapper et filtrer un tableau en même temps en Javascript
J'ai un tableau d'objets que je veux parcourir pour produire un nouveau filtré tableau. Mais aussi, j'ai besoin de filtrer certains des objets du nouveau tableau en fonction d'un paramètre. J'essaie ceci:
function renderOptions(options) {
return options.map(function (option) {
if (!option.assigned) {
return (someNewObject);
}
});
}
Est-ce une bonne approche? Est-il une meilleure méthode? Je suis ouvert à utiliser n'importe quelle bibliothèque telle que lodash.
8 réponses
Vous devriez utiliser Array.reduce
pour cela.
var options = [
{ name: 'One', assigned: true },
{ name: 'Two', assigned: false },
{ name: 'Three', assigned: true },
];
var reduced = options.reduce(function(filtered, option) {
if (option.assigned) {
var someNewValue = { name: option.name, newProperty: 'Foo' }
filtered.push(someNewValue);
}
return filtered;
}, []);
document.getElementById('output').innerHTML = JSON.stringify(reduced);
<h1>Only assigned options</h1>
<pre id="output"> </pre>
Plus d'Informations: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
Utiliser réduire, Luke!
function renderOptions(options) {
return options.reduce(function (res, option) {
if (!option.assigned) {
res.push(someNewObject);
}
return res;
}, []);
}
Une ligne reduce
avec ES6 fantaisie propagation de la syntaxe, c'est ici!
var options = [
{ name: 'One', assigned: true },
{ name: 'Two', assigned: false },
{ name: 'Three', assigned: true },
];
const filtered = options
.reduce((result, {name, assigned}) => [...result, ...assigned ? [name] : []], []);
console.log(filtered);
Avec ES6 vous pouvez le faire très court:
options.filter(opt => !opt.assigned).map(opt => someNewObject)
Utiliser Tableau.prototype.filtre lui-même
function renderOptions(options) {
return options.filter(function(option){
return !option.assigned;
}).map(function (option) {
return (someNewObject);
});
}
En utilisant reduce, vous pouvez le faire dans un tableau.prototype de la fonction. Cela récupérera tous les nombres pairs d'un tableau.
var arr = [1,2,3,4,5,6,7,8];
var brr = arr.reduce(function(c,n){
if(n%2!=0){
return c;
}
c.push(n);
return c;
},[]);
document.getElementById('mypre').innerHTML = brr.toString();
<h1>Get all even numbers</h1>
<pre id="mypre"> </pre>
Vous pouvez utiliser la même méthode et la généraliser pour vos objets, comme ceci.
var arr = options.reduce(function(c,n){
if(somecondition){return c;}
c.push(n); return c;
},[]);
arr
contient maintenant les objets filtrés.
J'ai optimisé les réponses avec les points suivants:
- réécrire
if (cond) { stmt; }
commecond && stmt;
- Utiliser ES6 Flèche Fonctions
Je vais présenter deux solutions, l'une en utilisant forEach, l'autre en utilisant reduce :
Solution 1: utiliser forEach
var options = [
{ name: 'One', assigned: true },
{ name: 'Two', assigned: false },
{ name: 'Three', assigned: true },
];
var reduced = []
options.forEach(o => {
o.assigned && reduced.push( { name: o.name, newProperty: 'Foo' } );
} );
console.log(reduced);
Solution 2: Utilisation de réduire
var options = [
{ name: 'One', assigned: true },
{ name: 'Two', assigned: false },
{ name: 'Three', assigned: true },
];
var reduced = options.reduce((a, o) => {
o.assigned && a.push( { name: o.name, newProperty: 'Foo' } );
return a;
}, [ ] );
console.log(reduced);
Je vous laisse décider quelle solution choisir.
À un moment donné, n'est-il pas plus facile(ou tout aussi facile) d'utiliser un forEach
var options = [
{ name: 'One', assigned: true },
{ name: 'Two', assigned: false },
{ name: 'Three', assigned: true },
];
var reduced = []
options.forEach(function(option) {
if (option.assigned) {
var someNewValue = { name: option.name, newProperty: 'Foo' }
reduced.push(someNewValue);
}
});
document.getElementById('output').innerHTML = JSON.stringify(reduced);
<h1>Only assigned options</h1>
<pre id="output"> </pre>
Cependant, ce serait bien s'il y avait une fonction malter()
ou fap()
qui combine les fonctions map
et filter
. Cela fonctionnerait comme un filtre, sauf qu'au lieu de renvoyer true ou false, il retournerait n'importe quel objet ou un null/undefined.