是的,Array.map() 或者 $.map() 做的是同样的事情。
var ids = this.fruits.map(function(v){
return v.Id;
});
var ids2 = $.map(this.fruits, function (v){
return v.Id;
});
console.log(ids, ids2);
http://jsfiddle.net/NsCXJ/1/
由于旧浏览器不支持 array.map 方法,建议您使用 jQuery 方法。
如果您出于某些原因喜欢另一种方法,可以为旧浏览器添加 polyfill 支持。
您也可以向数组原型添加自定义方法:
Array.prototype.select = function(expr){
var arr = this;
return arr.map(expr);
};
var ids = this.fruits.select(function(v){
return v.Id;
});
如果您传递一个字符串,可以使用函数构造器的扩展版本。也许可以玩一下:
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/
更新:
由于此回答变得如此流行,我添加了类似的 where()
+ firstOrDefault()
。这些也可以与基于字符串的函数构造器方法一起使用(这是最快的方法),但这里是使用对象字面量作为过滤器的另一种方法:
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;
collection = $.grep(collection, function (item) {
return item[property] === filter[property];
});
}
return collection.slice(0);
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;
};
用法:
var persons = [{ name: 'foo', age: 1 }, { name: 'bar', age: 2 }];
var result1 = persons.where({ age: 1, name: 'foo' });
var result2 = persons.firstOrDefault({ age: 1, name: 'foo' });
这里有一个jsperf测试,用于比较函数构造器和对象字面量的速度。如果您决定使用前者,请记住正确引用字符串。
我个人偏好于在筛选1-2个属性时使用基于对象字面量的解决方案,并为更复杂的过滤传递回调函数。
我将以两个通用提示结束,在向本地对象原型添加方法时请注意:
在覆盖现有方法之前检查其是否存在,例如:
if(!Array.prototype.where) {
Array.prototype.where = ...
如果您不需要支持IE8及以下版本,请使用Object.defineProperty定义方法,使它们成为不可枚举的。如果有人在数组上使用了for..in
(这本来就是错误的),他们也将迭代可枚举属性。只是提醒一下。
return typeof item[property] === 'function' ? item[property]() === filter[property] : item[property] === filter[property];
- Linus Caldwellreturn ko.unwrap(item[property]) === filter[property]
? - Johan