Sí, Array.map () o $ .map () hace lo mismo.
//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/
Dado que array.map no es compatible con navegadores antiguos, le sugiero que siga con el método jQuery.
Si prefiere el otro por alguna razón, siempre puede agregar un polyfill para el soporte antiguo del navegador.
Siempre puede agregar métodos personalizados al prototipo de matriz también:
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;
});
Una versión extendida que usa el constructor de funciones si pasa una cadena. Algo para jugar, tal vez:
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/
Actualizar:
Como esta se ha convertido en una respuesta tan popular, agrego mi where()
+ similar firstOrDefault()
. Estos también podrían usarse con el enfoque del constructor de funciones basado en cadenas (que es el más rápido), pero aquí hay otro enfoque que usa un objeto literal como filtro:
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;
};
Uso:
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' });
Aquí hay una prueba de jsperf para comparar el constructor de funciones frente a la velocidad literal del objeto. Si decide usar el primero, recuerde citar las cadenas correctamente.
Mi preferencia personal es usar las soluciones basadas en literales de objeto al filtrar 1-2 propiedades, y pasar una función de devolución de llamada para un filtrado más complejo.
Terminaré esto con 2 consejos generales al agregar métodos a los prototipos de objetos nativos:
Verifique la existencia de métodos existentes antes de sobrescribir, por ejemplo:
if(!Array.prototype.where) {
Array.prototype.where = ...
Si no necesita admitir IE8 y versiones posteriores, defina los métodos con Object.defineProperty para que no se puedan enumerar . Si alguien usó for..in
en una matriz (lo cual es incorrecto en primer lugar), también iterará propiedades enumerables. Solo un aviso.