是的,Array.map()或$.map()做同樣的事情。
//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/
由於array.map不能在較早的瀏覽器支持,我建議你還是堅持使用jQuery的方法。
如果您因爲某種原因更喜歡另一個,則可以隨時添加一個polyfill以實現舊的瀏覽器支持。
您可以隨時添加自定義方法的陣列原型,以及:
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;
});
如果你傳遞一個字符串,使用函數構造函數的擴展版本。東西玩弄也許是:
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; // 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;
};
用法:
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' });
這裏是一個jsperf test來比較函數構造函數與對象文字速度。如果您決定使用前者,請記住正確引用字符串。
我個人的偏好是在過濾1-2個屬性時使用基於對象字面值的解決方案,併爲更復雜的過濾傳遞迴調函數。
if(!Array.prototype.where) { Array.prototype.where = ...
如果您:覆蓋如之前
檢查的現有方法發生:
我會添加方法原生對象原型,用時2個一般提示結束這不需要支持IE8及以下版本,請使用Object.defineProperty定義方法,使它們不可枚舉。如果有人在數組上使用了for..in
(這首先是錯誤的) 它們也會迭代枚舉屬性。只是一個頭。
@ChrisNevill我添加了一個字符串版本,以防萬一你intrested – Johan
@MUlferts良好的捕獲,更新:)。現在我建議使用lodash來完成這些任務。他們公開了與上面的代碼相同的接口 – Johan
爲了支持knockout observables:'return typeof item [property] ==='function'? item [property]()=== filter [property]:item [property] === filter [property];' –