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 fournira undefined
. J'opterais pour une reduce
solution, qui peut simplement ignorer la propriété ou même vous définir une valeur par défaut.
function getFields(list, field) {
// reduce the provided list to an array only containing the requested field
return list.reduce(function(carry, item) {
// check if the item is actually an object and does contain the field
if (typeof item === 'object' && field in item) {
carry.push(item[field]);
}
// return the 'carry' (which is the list of matched field values)
return carry;
}, []);
}
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.
function getFields(list, field, otherwise) {
// reduce the provided list to an array containing either the requested field or the alternative value
return list.reduce(function(carry, item) {
// If item is an object and contains the field, add its value and the value of otherwise if not
carry.push(typeof item === 'object' && field in item ? item[field] : otherwise);
// return the 'carry' (which is the list of matched field values)
return carry;
}, []);
}
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 a reduce
):
function getFields(list, field, otherwise) {
// map the provided list to an array containing either the requested field or the alternative value
return list.map(function(item) {
// If item is an object and contains the field, add its value and the value of otherwise if not
return typeof item === 'object' && field in item ? item[field] : otherwise;
}, []);
}
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.
function getFields(list, field, otherwise) {
// determine once whether or not to use the 'otherwise'
var alt = typeof otherwise !== 'undefined';
// reduce the provided list to an array only containing the requested field
return list.reduce(function(carry, item) {
// If item is an object and contains the field, add its value and the value of 'otherwise' if it was provided
if (typeof item === 'object' && field in item) {
carry.push(item[field]);
}
else if (alt) {
carry.push(otherwise);
}
// return the 'carry' (which is the list of matched field values)
return carry;
}, []);
}
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.
function getFields(list, field, otherwise) {
var alt = typeof otherwise !== 'undefined';
return list.reduce(function(carry, item) {
return carry.concat(typeof item === 'object' && field in item ? item[field] : (alt ? otherwise : []));
}, []);
}
exemple jsbin
var foos = objArray.pluck("foo");
.