2014-08-28 9 views
20

Ich benutze UnderscoreJs. Betrachten Sie diesen Code:Was ist der Unterschied zwischen Unterstrich _.each und _.map?

var docs = [ 
    {name : 'Anders', niche : 'Web Development'}, 
    {name : 'Johnny', niche : 'Design'}, 
    {name : 'Eric', niche : 'PhotoShop'} 
]; 

var newDocs = _.map(docs, function (doc){ 
    delete doc.niche; 
    return doc; 
}); 

Es spielt keine Rolle, ob ich .each oder .map hier verwenden. Das Ergebnis ist genau dasselbe.

Was ist eigentlich der Unterschied zwischen den beiden im obigen Fall?

+1

welche Bibliothek, unterstreichen? – Mritunjay

+1

Lesen Sie [die Manpage] (http://documentcloud.github.io/underscore/docs/underscore.html#section-13), es ist nicht so schwer, es nachzuschlagen. – Nit

+1

'_.each()' * iteriert *, '_.map()' * projects *, d. H. Erstellt ein neues Array aus dem als Eingabe übergebenen Array, wobei die angegebene Funktion zum Erstellen der neuen Elemente verwendet wird. –

Antwort

27

map sollte ein funktionales Mapping-Verfahren sein: seine Funktion Argument einen Wert zurückgeben sollte, aber hierbei keine Nebenwirkungen zu erwarten.

each ist nur ein funktioneller Ersatz für eine zwingend for Schleife: Sein Zweck ist es, eine Wirkung zu haben, und es ist keinen Wert zurückzuerwartet.

Zum Beispiel wäre dies eine angemessenere Nutzung seines für map:

var docs = getDocs(); 
var docTitles = _.map(docs, function (doc){ 
    return doc.title; 
}); 
// expect `docs` to be unchanged 

Während dies wäre eine geeignete Verwendung für each sein:

var docs = getDocs(); 
_.each(docs, function (doc){ 
    delete doc.niche; 
}); 
// expect `docs` to be altered. 
7

_.each (list, iteratee)

Iteriert über eine Liste von Elementen, die jeweils wiederum an eine iteratee Funktion ergibt.

Jeder Aufruf von iteratee wird mit drei Argumenten aufgerufen: (Element, Index, Liste). Wenn list ein JavaScript-Objekt ist, werden iteratees Argumente (Wert, Schlüssel, Liste) sein. Gibt die Liste für die Verkettung zurück.

_.each({one: 1, two: 2, three: 3}, alert); 
=> alerts each number value in turn... 

_.map (list, iteratee)

Erzeugt ein neues Array von Werten, indem jeder Wert in die Liste Abbilden durch eine Transformationsfunktion (iteratee).

Wenn die Liste ein JavaScript-Objekt ist, werden iteratees Argumente (Wert, Schlüssel, Liste) sein.

_.map({one: 1, two: 2, three: 3}, function(num, key){ return num * 3; }); 
=> [3, 6, 9] 

siehe documentation

2

Ihre Behauptung, dass die Ergebnisse „genau die dasselbe "ist unwahr. Die _.each() Funktion gibt die ursprüngliche Liste zurück, aber _.map() gibt eine neue Liste zurück. Sie ändern die Originalobjekte direkt, während Sie fortfahren, sodass Sie in jeder Liste Verweise auf dieselben Objekte erhalten, aber mit _.map() enden Sie mit zwei separaten Array-Instanzen.

3

Sie können auf den Quellcode schauen nur den Unterschied zu sehen:

  • _.each:

    _.each = _.forEach = function(obj, iteratee, context) { 
        if (obj == null) return obj; 
        iteratee = createCallback(iteratee, context); 
        var i, length = obj.length; 
        if (length === +length) { 
         for (i = 0; i < length; i++) { 
         iteratee(obj[i], i, obj); 
         } 
        } else { 
         var keys = _.keys(obj); 
         for (i = 0, length = keys.length; i < length; i++) { 
         iteratee(obj[keys[i]], keys[i], obj); 
         } 
        } 
        return obj; 
    }; 
    
  • _.map:

    _.map = _.collect = function(obj, iteratee, context) { 
        if (obj == null) return []; 
        iteratee = _.iteratee(iteratee, context); 
        var keys = obj.length !== +obj.length && _.keys(obj), 
         length = (keys || obj).length, 
         results = Array(length), 
         currentKey; 
        for (var index = 0; index < length; index++) { 
         currentKey = keys ? keys[index] : index; 
         results[index] = iteratee(obj[currentKey], currentKey, obj); 
        } 
        return results; 
    }; 
    
Verwandte Themen