Ja, Array.map () oder $ .map () machen dasselbe.
//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/
Da array.map in älteren Browsern nicht unterstützt wird, sollten Sie sich an die jQuery-Methode halten.
Wenn Sie aus irgendeinem Grund die andere bevorzugen, können Sie jederzeit eine Polyfüllung für die Unterstützung alter Browser hinzufügen.
Sie können dem Array-Prototyp auch jederzeit benutzerdefinierte Methoden hinzufügen:
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;
});
Eine erweiterte Version, die den Funktionskonstruktor verwendet, wenn Sie eine Zeichenfolge übergeben. Vielleicht etwas zum Herumspielen:
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/
Aktualisieren:
Da dies eine so beliebte Antwort geworden ist, füge ich ähnlich mein where()
+ hinzu firstOrDefault()
. Diese können auch mit dem String-basierten Funktionskonstruktor-Ansatz (der am schnellsten ist) verwendet werden. Hier ist jedoch ein anderer Ansatz, bei dem ein Objektliteral als Filter verwendet wird:
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;
};
Verwendung:
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' });
Hier ist ein jsperf-Test , um den Funktionskonstruktor mit der Objektliteralgeschwindigkeit zu vergleichen. Wenn Sie sich für Ersteres entscheiden, denken Sie daran, Zeichenfolgen korrekt zu zitieren.
Meine persönliche Präferenz ist es, beim Filtern von 1-2 Eigenschaften die auf Objektliteral basierenden Lösungen zu verwenden und eine Rückruffunktion für eine komplexere Filterung zu übergeben.
Ich werde dies mit zwei allgemeinen Tipps beenden, wenn Sie Methoden zu nativen Objektprototypen hinzufügen:
Überprüfen Sie vor dem Überschreiben, ob vorhandene Methoden vorhanden sind, z.
if(!Array.prototype.where) {
Array.prototype.where = ...
Wenn Sie IE8 und niedriger nicht unterstützen müssen, definieren Sie die Methoden mit Object.defineProperty , um sie nicht aufzählbar zu machen. Wenn jemand for..in
ein Array verwendet (was an erster Stelle falsch ist), iteriert er auch aufzählbare Eigenschaften. Nur ein Kopf hoch.