Oui, Array.map() ou $.map() font la même chose.
//array.map:
var ids = this.fruits.map(function(v){
return v.Id;
});
//jQuery.map:
var ids2 = $.map(this.fruits, function (v){
return v.Id;
});
console.log(ids, ids2);
http://jsfiddle.net/NsCXJ/1/
Puisque array.map n'est pas supporté dans les anciens navigateurs, je suggère de rester avec la méthode jQuery.
Si vous préférez l'autre pour une raison quelconque, vous pouvez toujours ajouter un polyfill pour un support des anciens navigateurs.
Vous pouvez toujours ajouter des méthodes personnalisées au prototype d'array également:
Array.prototype.select = function(expr){
var arr = this;
//faire des choses personnalisées
return arr.map(expr); //ou $.map(expr);
};
var ids = this.fruits.select(function(v){
return v.Id;
});
Une version étendue qui utilise le constructeur de fonction si vous passez une chaîne. Quelque chose à expérimenter peut-être:
Array.prototype.select = function(expr){
var arr = this;
switch(typeof expr){
case 'function':
return $.map(arr, expr);
break;
case 'string':
try{
var func = new Function(expr.split('.')[0],
'return ' + expr + ';');
return $.map(arr, func);
}catch(e){
return null;
}
break;
default:
throw new ReferenceError('expr non défini ou non supporté');
break;
}
};
console.log(fruits.select('x.Id'));
http://jsfiddle.net/aL85j/
Mise à jour:
Puisque cela est devenu une réponse si populaire, j'ajoute ma méthode where()
+ firstOrDefault()
similaires. Celles-ci pourraient également être utilisées avec l'approche du constructeur de fonction basée sur une chaîne (qui est la plus rapide), mais voici une autre approche utilisant un objet littéral comme filtre:
Array.prototype.where = function (filter) {
var collection = this;
switch(typeof filter) {
case 'function':
return $.grep(collection, filter);
case 'object':
for(var property in filter) {
if(!filter.hasOwnProperty(property))
continue; // ignorer les propriétés héritées
collection = $.grep(collection, function (item) {
return item[property] === filter[property];
});
}
return collection.slice(0); // copie du tableau
// (en cas de filtre vide)
default:
throw new TypeError('func doit être soit une ' +
'fonction, soit un objet de propriétés et de valeurs à filtrer par');
}
};
Array.prototype.firstOrDefault = function(func){
return this.where(func)[0] || null;
};
Utilisation:
var persons = [{ name: 'foo', age: 1 }, { name: 'bar', age: 2 }];
// retourne un tableau avec un élément:
var result1 = persons.where({ age: 1, name: 'foo' });
// retourne le premier élément correspondant dans le tableau, ou null s'il n'y a pas de correspondance
var result2 = persons.firstOrDefault({ age: 1, name: 'foo' });
Voici un test jsperf pour comparer la vitesse du constructeur de fonction par rapport à l'objet littéral. Si vous décidez d'utiliser le premier, rappelez-vous de citer correctement les chaînes.
Ma préférence personnelle est d'utiliser les solutions basées sur des objets littéraux lors du filtrage de 1 à 2 propriétés, et de passer une fonction de rappel pour un filtrage plus complexe.
Je terminerai avec 2 conseils généraux lors de l'ajout de méthodes aux prototypes d'objets natifs:
-
Vérifiez l'existence de méthodes existantes avant de les écraser par exemple:
if(!Array.prototype.where) { Array.prototype.where = ...
-
Si vous n'avez pas besoin de prendre en charge IE8 et versions antérieures, définissez les méthodes en utilisant Object.defineProperty pour les rendre non énumérables. Si quelqu'un utilisait for..in
sur un tableau (ce qui est incorrect en premier lieu), il itérera également sur les propriétés énumérables. Juste une mise en garde.