Подтвердить что ты не робот

В чем разница между подчеркиванием _.each и _.map?

Я использую UnderscoreJs. Рассмотрим этот код:

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

Не имеет значения, использую ли я здесь .each или .map. Результат точно такой же.

На самом деле разница между двумя в приведенном выше случае?

4b9b3361

Ответ 1

map предназначен для функционального метода сопоставления: его аргумент функции должен возвращать значение, но не ожидается каких-либо побочных эффектов.

each является просто функциональной заменой императивного цикла for: его цель состоит в том, чтобы иметь эффект, и он не должен возвращать какое-либо значение.

Например, это было бы более подходящим для map:

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

В то время как это было бы подходящим использованием для each:

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

Ответ 2

_. each (list, iteratee)

Итерации над списком элементов, каждый из которых приводит к итерационной функции.

Каждый вызов iteratee вызывается с тремя аргументами: (element, index, list). Если список является объектом JavaScript, аргументы iteratee будут (значение, ключ, список). Возвращает список цепочки.

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

_. map (list, iteratee)

Создает новый массив значений, отображая каждое значение в списке через функцию преобразования (iteratee).

Если список является объектом JavaScript, аргументы iteratee будут (значение, ключ, список).

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

см. документация

Ответ 3

Вы можете просто посмотреть исходный код, чтобы увидеть разницу:

  • _.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;
    };
    

Ответ 4

Ваше утверждение о том, что результаты "точно такие же", неверно. Функция _.each() возвращает исходный список, но _.map() возвращает новый список. Вы сами изменяете исходные объекты по ходу, поэтому вы получаете ссылки на одни и те же объекты в каждом списке, но с _.map() вы получаете два отдельных экземпляра массива.