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

Есть ли разница между foreach и картой?

Хорошо, это скорее вопрос компьютерной науки, чем вопрос, основанный на конкретном языке, но есть ли разница между операцией карты и операцией foreach? Или они просто разные имена для одного и того же?

4b9b3361

Ответ 1

Different.

foreach выполняет итерацию по списку и применяет некоторую операцию с побочными эффектами к каждому элементу списка (например, сохранение каждого из них в базе данных, например)

отображает итерации по списку, преобразует каждый член этого списка и возвращает другой список того же размера с преобразованными членами (например, преобразование списка строк в верхний регистр)

Ответ 2

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

Ответ 3

Короче говоря, foreach предназначен для применения операции к каждому элементу набора элементов, тогда как map предназначен для преобразования одной коллекции в другую.

Существуют два существенных различия между foreach и map.

  • foreach не имеет концептуальных ограничений для применяемой операции, кроме, возможно, принимает элемент как аргумент. То есть операция может ничего не делать, может иметь побочный эффект, может возвращать значение или не может возвращать значение. Все foreach заботятся об итерации по набору элементов и применяют операцию для каждого элемента.

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

  • foreach работает с одним набором элементов. Это входная коллекция.

    map работает с двумя наборами элементов: сбор данных и выходная коллекция.

Нельзя связывать два алгоритма: на самом деле вы можете просмотреть эти два иерархически, где map является специализацией foreach. То есть вы можете использовать foreach и заставить операцию преобразовать свой аргумент и вставить его в другую коллекцию. Таким образом, алгоритм foreach представляет собой абстракцию, обобщение алгоритма map. Фактически, поскольку foreach не имеет никакого ограничения на его работу, мы можем с уверенностью сказать, что foreach - самый простой механизм петли, и он может делать все, что может сделать цикл. map, а также другие более специализированные алгоритмы, существуют для выразительности: если вы хотите сопоставить (или преобразовать) одну коллекцию в другую, ваше намерение станет более ясным, если вы используете map, чем если бы вы использовали foreach.

Мы можем продолжить это обсуждение и рассмотреть алгоритм copy: цикл, который клонирует коллекцию. Этот алгоритм также является специализацией алгоритма foreach. Вы можете определить операцию, которая, учитывая элемент, вставляет тот же самый элемент в другую коллекцию. Если вы используете foreach с этой операцией, вы фактически выполнили алгоритм copy, хотя и с уменьшенной ясностью, выразительностью или очевидностью. Пусть это еще больше: мы можем сказать, что map является специализацией copy, которая сама является специализацией foreach. map может изменить любой из элементов, которые он повторяет. Если map не меняет ни один из элементов, он просто копирует элементы, а использование копии выражает намерение более четко.

Сам алгоритм foreach может иметь или не иметь возвращаемое значение, в зависимости от языка. Например, в С++ foreach возвращает первоначально полученную операцию. Идея состоит в том, что операция может иметь состояние, и вам может понадобиться эта операция, чтобы проверить, как она эволюционировала над элементами. map тоже может вернуть или не вернуть значение. В С++ transform (эквивалент для map здесь) происходит возврат итератора в конец выходного контейнера (коллекции). В Ruby возвращаемое значение map представляет собой последовательность вывода (сбор). Таким образом, возвращаемое значение алгоритмов - это действительно деталь реализации; их эффект может быть или не быть тем, что они возвращают.

Ответ 4

Array.protototype.map и Array.protototype.forEach оба очень похожи.

Выполните следующий код: http://labs.codecademy.com/bw1/6#:workspace

var arr = [1, 2, 3, 4, 5];

arr.map(function(val, ind, arr){
    console.log("arr[" + ind + "]: " + Math.pow(val,2));
});

console.log();

arr.forEach(function(val, ind, arr){
    console.log("arr[" + ind + "]: " + Math.pow(val,2));
});

Они дают точный результат.

arr[0]: 1
arr[1]: 4
arr[2]: 9
arr[3]: 16
arr[4]: 25

arr[0]: 1
arr[1]: 4
arr[2]: 9
arr[3]: 16
arr[4]: 25

Но твист возникает, когда вы запускаете следующий код: -

Здесь я просто назначил результат возвращаемого значения из методов map и forEach.

var arr = [1, 2, 3, 4, 5];

var ar1 = arr.map(function(val, ind, arr){
    console.log("arr[" + ind + "]: " + Math.pow(val,2));
    return val;
});

console.log();
console.log(ar1);
console.log();

var ar2 = arr.forEach(function(val, ind, arr){
    console.log("arr[" + ind + "]: " + Math.pow(val,2));
    return val;
});

console.log();
console.log(ar2);
console.log();

Теперь результат - это нечто сложное!

arr[0]: 1
arr[1]: 4
arr[2]: 9
arr[3]: 16
arr[4]: 25

[ 1, 2, 3, 4, 5 ]

arr[0]: 1
arr[1]: 4
arr[2]: 9
arr[3]: 16
arr[4]: 25

undefined

Заключение

Array.prototype.map возвращает массив, но Array.prototype.forEach нет. Таким образом, вы можете манипулировать возвращенным массивом внутри функции обратного вызова, переданной методу карты, и затем вернуть его.

Array.prototype.forEach проходит только через данный массив, чтобы вы могли делать свой материал во время ходьбы по массиву.

Ответ 5

самая "видимая" разница заключается в том, что карта накапливает результат в новой коллекции, а foreach - только для самого выполнения.

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

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

Ответ 6

Короткий ответ: map и forEach разные. Кроме того, неофициально говоря, map является строгим надмножеством forEach.

Длинный ответ: Сначала давайте рассмотрим однострочные описания forEach и map:

  • forEach выполняет итерацию по всем элементам, вызывая функцию, указанную в каждой из них.
  • map выполняет итерацию по всем элементам, вызывая предоставленную функцию на каждом и производит преобразованный массив, запоминая результат каждого вызова функции.

Во многих языках forEach часто называют просто each. В следующем обсуждении JavaScript используется только для справки. Это может быть любой другой язык.

Теперь можно использовать каждую из этих функций.

Использование forEach:

Задача 1: Напишите функцию printSquares, которая принимает массив чисел arr и печатает квадрат каждого элемента в нем.

Решение 1:

var printSquares = function (arr) {
    arr.forEach(function (n) {
        console.log(n * n);
    });
};

Использование map:

Задача 2: Напишите функцию selfDot, которая принимает массив чисел arr и возвращает массив, в котором каждый элемент является квадратом соответствующего элемента в arr.

Кроме того: здесь, в сленговых терминах, мы пытаемся построить квадрат входного массива. Формально мы пытаемся вычислить его точечный продукт с собой.

Решение 2:

var selfDot = function (arr) {
    return arr.map(function (n) {
        return n * n;
    });
};

Как map надмножество forEach?

Вы можете использовать map для решения обеих задач, Задача 1 и Задача 2. Однако вы не можете использовать forEach для решения Задачи 2.

В Решение 1, если вы просто замените forEach на map, решение останется в силе. Однако в решении 2 замена map на forEach приведет к поломке вашего ранее работающего решения.

Реализация forEach в терминах map:

Другим способом реализации превосходства map является реализация forEach в терминах map. Поскольку мы хорошие программисты, мы не будем заниматься загрязнением пространства имен. Мы будем называть наш forEach, просто each.

Array.prototype.each = function (func) {
    this.map(func);
};

Теперь, если вам не нравится ерунда prototype, вот вы:

var each = function (arr, func) {
    arr.map(func); // Or map(arr, func);
};

Итак, ммм.. Почему существует forEach?

Ответ - эффективность. Если вам не интересно преобразовать массив в другой массив, зачем вам вычислять преобразованный массив? Только сбросить его? Конечно нет! Если вам не нужна трансформация, вы не должны делать преобразования.

Таким образом, хотя карта может использоваться для решения Задачи 1, она, вероятно, не должна. Для каждого это правильный кандидат для этого.


Оригинальный ответ:

Хотя я в основном согласен с ответом @madlep, я хотел бы указать, что map() является строгим супер-установленным forEach().

Да, map() обычно используется для создания нового массива. Однако для изменения текущего массива может использоваться также.

Вот пример:

var a = [0, 1, 2, 3, 4], b = null;
b = a.map(function (x) { a[x] = 'What!!'; return x*x; });
console.log(b); // logs [0, 1, 4, 9, 16] 
console.log(a); // logs ["What!!", "What!!", "What!!", "What!!", "What!!"]

В приведенном выше примере a удобно установить таким образом, чтобы a[i] === i для i < a.length. Тем не менее, он демонстрирует силу map().

Вот официальное описание map(). Обратите внимание, что map() может даже изменить массив, на который он вызывается! Приветствуем map().

Надеюсь, что это помогло.


Отредактировано 10-ноя-2015: Добавлена ​​разработка.

Ответ 7

Вот пример в Scala, используя списки: map returns list, foreach ничего не возвращает.

def map(f: Int ⇒ Int): List[Int]
def foreach(f: Int ⇒ Unit): Unit

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

scala> val list = List(1, 2, 3)
list: List[Int] = List(1, 2, 3)

scala> list map (x => x * 2)
res0: List[Int] = List(2, 4, 6)

Foreach просто применяет f к каждому элементу:

scala> var sum = 0
sum: Int = 0

scala> list foreach (sum += _)

scala> sum
res2: Int = 6 // res1 is empty

Ответ 8

Если вы говорите о Javascript в частности, разница в том, что map является функцией цикла, а forEach является итератором.

Используйте map, когда вы хотите применить операцию к каждому члену списка и вернуть результаты в виде нового списка, не затрагивая исходный список.

Используйте forEach, если вы хотите что-то сделать на основе каждого элемента списка. Например, вы можете добавлять вещи на страницу. По сути, это здорово, когда вы хотите "побочные эффекты".

Другие отличия: forEach ничего не возвращает (поскольку это действительно функция потока управления), а переданная функция получает ссылки на индекс и весь список, тогда как карта возвращает новый список и проходит только в текущем элемент.