2015-09-18 7 views
13

Ich versuche, alle Elemente in einem Array, die größer als 10 sind, zu einem neuen Array zu filtern. Ich verwende absichtlich nicht Array.prototype.filter(), da ich die reduce() Methode erlernen möchte. Hier ist der Code, ich spiele mitWarum nimmt Array.prototype.reduce() kein leeres Array als Akkumulator an?

var collection = [3, 5, 11, 23, 1]; 
 

 
// fileter all the elements bigger than 10 to a new array 
 

 
var output = collection.reduce(function(filteredArr, collectionElemet) { 
 
    if (collectionElemet > 10) { 
 
    return filteredArr.push(collectionElemet); 
 
    } 
 
}, []);

Ich hatte erwartet, dass filteredArr würde zum Zeitpunkt der ersten Rückruf Ausführung mit einem leeren Array initialisiert werden, da es mit vielen Beispielen geschieht here zur Verfügung gestellt. Aber wenn ich diesen Code ausführen, bekomme ich den Fehler Cannot read property 'push' of undefined, wo ich es vermasseln? Vielen Dank!

+0

Wenn die Bedingung wahr ist - Sie geben eine Zahl zurück, wenn sie nicht wahr ist - geben Sie ein 'undefined' zurück. Wenn Sie nur filtern wollen - verwenden Sie 'Array.prototype.filter ', ist Ihr aktueller Code so, wie er ist, hässlich und irreführend. – zerkms

+0

@zerkms: Das ist fair für Produktionscode, nicht für Bildung/Experimente. Das OP stellt klar, dass er über "Filter" Bescheid weiß, aber versucht "Reduce" zu verstehen. – Amadan

+1

@Amadan dann ist es ein schwacher Versuch: es macht Sinn zu versuchen, Funktionen zu verstehen, die Usecases verwenden, für die sie entworfen wurden. – zerkms

Antwort

26

Sie müssen die filteredArr von Ihrer anonymen Funktion zurückzukehren, so dass sie als previousValue für den nächsten Anruf verwendet wird

var collection = [3, 5, 11, 23, 1]; 

// filter all the elements bigger than 10 to a new array 

var output = collection.reduce(function(filteredArr, collectionElement) { 
    if (collectionElement > 10) { 
    filteredArr.push(collectionElement); 
    } 
    return filteredArr; 
}, []); 
4

Array.prototype.push wird die Länge des neuen Arrays zurück. Sie müssen den Akku zurückgeben. Eine prägnante Art und Weise, dies zu tun ist mit Array.prototype.concat, da diese Methode tatsächlich das Array zurück:

var collection = [3, 5, 11, 23, 1]; 

var output = collection.reduce(function(filteredArr, collectionElemet) { 
    if (collectionElemet > 10) { 
    return filteredArr.concat(collectionElemet); 
    } 
}, []); 

Sie haben die Speicher zurück, so dass die nächste Iteration den Wert des Speichers verwenden kann.

+0

Nicht mein Downvote, aber * concat * gibt jedes Mal ein neues Array zurück, was ineffizient ist. * push * ist die offensichtliche Wahl für das Hinzufügen neuer Elemente zu einem bestehenden Array. – RobG

+1

Nicht immer geht es um Effizienz, ist gültige Antwort, weil zwei Dinge zu veranschaulichen, wie Sie eine Lösung in einer Zeile und das @ segmentationfaulter muss filteredArr zurückgegeben werden. Seine Verwirrung war wahrscheinlich, dass filteredArr.push filteredArr zurückgibt. – titusfx

Verwandte Themen