Oui, Array.map () ou $ .map () fait 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 pris en charge dans les navigateurs plus anciens, je vous suggère de vous en tenir à la méthode jQuery.
Si vous préférez l'autre pour une raison quelconque, vous pouvez toujours ajouter un polyfill pour le support des anciens navigateurs.
Vous pouvez également ajouter des méthodes personnalisées au prototype de tableau:
Array.prototype.select = function(expr){
var arr = this;
//do custom stuff
return arr.map(expr); //or $.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 pour jouer avec 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 not defined or not supported');
break;
}
};
console.log(fruits.select('x.Id'));
http://jsfiddle.net/aL85j/
Mettre à jour:
Puisque cela est devenu une réponse si populaire, j'ajoute mon where()
+ similaire firstOrDefault()
. Ceux-ci pourraient également être utilisés 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 littéral d'objet 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; // ignore inherited properties
collection = $.grep(collection, function (item) {
return item[property] === filter[property];
});
}
return collection.slice(0); // copy the array
// (in case of empty object filter)
default:
throw new TypeError('func must be either a' +
'function or an object of properties and values to filter by');
}
};
Array.prototype.firstOrDefault = function(func){
return this.where(func)[0] || null;
};
Usage:
var persons = [{ name: 'foo', age: 1 }, { name: 'bar', age: 2 }];
// returns an array with one element:
var result1 = persons.where({ age: 1, name: 'foo' });
// returns the first matching item in the array, or null if no match
var result2 = persons.firstOrDefault({ age: 1, name: 'foo' });
Voici un test jsperf pour comparer le constructeur de fonction à la vitesse littérale de l'objet. Si vous décidez d'utiliser l'ancien, n'oubliez pas de citer correctement les chaînes.
Ma préférence personnelle est d'utiliser les solutions basées sur l'objet littéral lors du filtrage de 1 à 2 propriétés et de transmettre une fonction de rappel pour un filtrage plus complexe.
Je terminerai cela avec 2 conseils généraux lors de l'ajout de méthodes à des prototypes d'objets natifs:
Vérifiez l'occurrence des méthodes existantes avant d'écraser, par exemple:
if(!Array.prototype.where) {
Array.prototype.where = ...
Si vous n'avez pas besoin de prendre en charge IE8 et les versions antérieures , définissez les méthodes en utilisant Object.defineProperty pour les rendre non énumérables. Si quelqu'un a utilisé for..in
sur un tableau (ce qui est faux en premier lieu), il itérera également des propriétés énumérables. Juste un avertissement.