2014-08-28 13 views
20

Tôi đang sử dụng UnderscoreJs. Hãy xem xét mã này:Điểm khác biệt giữa dấu gạch dưới _.each và _.map là gì?

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; 
}); 

Nó không quan trọng nếu tôi sử dụng .each hoặc .map đây. Kết quả là chính xác như nhau.

Điều gì thực sự là sự khác biệt giữa hai trường hợp trên?

+1

gì thư viện, dấu gạch dưới? – Mritunjay

+1

Đọc [manpage] (http://documentcloud.github.io/underscore/docs/underscore.html#section-13), không khó để tìm kiếm nó. – Nit

+1

'_.each()' * iterates *, '_.map()' * projects *, tức là xây dựng một mảng mới từ mảng được truyền làm đầu vào, sử dụng hàm bạn chỉ định để xây dựng các phần tử mới. –

Trả lời

27

map được thiết kế để trở thành một phương pháp lập bản đồ chức năng: đối số chức năng của nó sẽ trả về một giá trị, nhưng dự kiến ​​sẽ không có bất kỳ tác dụng phụ.

each chỉ là một thay thế chức năng cho vòng lặp bắt buộc for: mục đích của nó là có hiệu lực và không được mong đợi trả lại bất kỳ giá trị.

Ví dụ, đây sẽ là một sử dụng thích hợp hơn cho map:

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

Trong khi điều này sẽ được sử dụng thích hợp cho each:

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

_.each (danh sách, iteratee)

lặp trên một danh sách các yếu tố, năng suất mỗi lần lượt đến một chức năng iteratee.

Mỗi lần gọi iteratee được gọi với ba đối số: (phần tử, chỉ mục, danh sách). Nếu danh sách là một đối tượng JavaScript, các đối số của iteratee sẽ là (giá trị, khóa, danh sách). Trả về danh sách cho chuỗi.

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

_.map (danh sách, iteratee)

Tạo một mảng mới của các giá trị bằng cách ánh xạ mỗi giá trị trong danh sách thông qua một hàm chuyển đổi (iteratee).

Nếu danh sách là đối tượng JavaScript, đối số của iteratee sẽ là (giá trị, khóa, danh sách).

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

thấy documentation

2

khẳng định của bạn mà kết quả là "chính xác cùng "là không đúng sự thật. Chức năng _.each() trả về danh sách gốc gốc, nhưng _.map() trả về một danh sách mới mới. Bạn đang trực tiếp sửa đổi các đối tượng gốc khi bạn đi, vì vậy bạn kết thúc với tham chiếu đến cùng một đối tượng trong mỗi danh sách, nhưng với _.map() bạn kết thúc với hai trường hợp mảng riêng biệt.

3

Bạn chỉ có thể nhìn vào mã nguồn để thấy sự khác biệt:

  • _.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; 
    }; 
    
Các vấn đề liên quan