Хорошо, это больше вопрос информатики, чем вопрос, основанный на конкретном языке, но есть ли разница между операцией отображения и операцией foreach? Или это просто разные имена для одной и той же вещи?
foreach
language-agnostic
computer-science
map-function
Роберт Гулд
источник
источник
Iterator[String]
отscala.io.Source.fromFile("/home/me/file").getLines()
и применить.foreach(s => ptintln(s))
к нему, он печатается нормально , но пустеет сразу после. В то же время, если я обращаюсь.map(ptintln(_))
к нему - он просто становится пустым и ничего не печатается.Ответы:
Разные.
foreach выполняет итерацию по списку и применяет некоторые операции с побочными эффектами к каждому члену списка (например, сохранение каждого из них в базе данных)
Карта выполняет итерацию по списку, преобразует каждого члена этого списка и возвращает другой список того же размера с преобразованными элементами (например, преобразование списка строк в верхний регистр)
источник
map
не делает , не приводит к исполнению лежащих в его основе логики , пока когда ожидаемый трансформируются список вызывается. В отличие от этого,foreach
операция вычисляется немедленно.Важное различие между ними заключается в том, что
map
все результаты накапливаются в коллекции, аforeach
ничего не возвращается.map
обычно используется, когда вы хотите преобразовать коллекцию элементов с помощью функции, тогда какforeach
просто выполняет действие для каждого элемента.источник
Короче говоря,
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
в C ++ возвращает первоначально полученную операцию. Идея состоит в том, что операция может иметь состояние, и вы можете захотеть, чтобы эта операция вернулась, чтобы проверить, как она развивалась над элементами.map
тоже может возвращать или не возвращать значение. В C ++transform
(здесь эквивалентmap
) происходит возврат итератора в конец контейнера вывода (коллекции). В Ruby возвращаемое значениеmap
является выходной последовательностью (коллекцией). Таким образом, возвращаемое значение алгоритмов действительно является деталью реализации; их эффект может быть или не быть тем, что они возвращают.источник
.forEach()
можно использовать для реализации.map()
, см. Здесь: stackoverflow.com/a/39159854/1524693Array.protototype.map
Метод &Array.protototype.forEach
очень похожи.Запустите следующий код: http://labs.codecademy.com/bw1/6#:workspace
Они дают точный тот же результат.
Но поворот возникает, когда вы запускаете следующий код:
Здесь я просто присвоил результат возвращаемого значения из карты и методы forEach.
Теперь результат чего-то сложного!
Вывод
Array.prototype.map
возвращает массив, ноArray.prototype.forEach
не делает. Таким образом, вы можете манипулировать возвращенным массивом внутри функции обратного вызова, переданной методу map, а затем вернуть его.Array.prototype.forEach
только проходит через данный массив, так что вы можете делать свои вещи во время обхода массива.источник
самое «видимое» отличие состоит в том, что map накапливает результат в новой коллекции, тогда как foreach выполняется только для самого выполнения.
но есть пара дополнительных предположений: поскольку «цель» карты - это новый список значений, на самом деле не имеет значения порядок выполнения. на самом деле, некоторые среды выполнения генерируют параллельный код или даже вводят некоторую запоминание, чтобы не вызывать повторяющиеся значения, или лень, чтобы вообще не вызывать некоторые.
foreach, с другой стороны, специально предназначен для побочных эффектов; поэтому порядок важен и обычно не может быть распараллелен.
источник
Краткий ответ:
map
иforEach
разные. Также, неофициально говоря,map
это строгий надмножествоforEach
.Длинный ответ: во- первых, давайте придумаем одну строку описания
forEach
иmap
:forEach
перебирает все элементы, вызывая предоставленную функцию для каждого элемента.map
перебирает все элементы, вызывая предоставленную функцию для каждого, и создает преобразованный массив, запоминая результат каждого вызова функции.На многих языках
forEach
часто называют простоeach
. Следующее обсуждение использует JavaScript только для справки. Это действительно может быть любой другой язык.Теперь давайте используем каждую из этих функций.
С помощью
forEach
:Задача 1: написать функцию
printSquares
, которая принимает массив чиселarr
и печатает квадрат каждого элемента в нем.Решение 1:
С помощью
map
:Задача 2: Напишите функцию
selfDot
, которая принимает массив чиселarr
и возвращает массив, в котором каждый элемент является квадратом соответствующего элемента вarr
.В сторону: здесь, в сленговом выражении, мы пытаемся выровнять входной массив. Формально говоря, мы пытаемся вычислить это точечное произведение с самим собой.
Решение 2:
Как
map
это суперсетforEach
?Вы можете использовать
map
для решения обеих задач, Задача 1 и Задача 2 . Тем не менее, вы не можете использоватьforEach
для решения задачи 2 .В решении 1 , если вы просто замените
forEach
егоmap
, решение все равно будет действовать. Однако в решении 2 заменаmap
наforEach
сломает ранее работавшее решение.Реализация
forEach
с точки зренияmap
:Еще один способ реализации
map
превосходства России заключается в реализацииforEach
с точки зренияmap
. Поскольку мы хорошие программисты, мы не будем баловаться загрязнением пространства имен. Мы позвоним нашимforEach
, простоeach
.Теперь, если вам не нравится
prototype
ерунда, вот и вы:Итак ... почему
forEach
существует?Ответ - эффективность. Если вы не заинтересованы в преобразовании массива в другой массив, зачем вам вычислять преобразованный массив? Только чтобы свалить это? Конечно нет! Если вы не хотите преобразование, вы не должны делать преобразование.
Таким образом, хотя карта может быть использована для решения задачи 1 , она, вероятно, не должна. Для каждого это правильный кандидат на это.
Оригинальный ответ:
Хотя я в основном согласен с ответом @madlep, я хотел бы отметить, что
map()
это строгий супер-набор изforEach()
.Да,
map()
обычно используется для создания нового массива. Тем не менее, он также может быть использован для изменения текущего массива.Вот пример:
В приведенном выше примере
a
было удобно установить так, чтобыa[i] === i
дляi < a.length
. Несмотря на это, он демонстрирует силуmap()
.Вот официальное описание
map()
. Обратите внимание, чтоmap()
может даже изменить массив, на котором он вызывается! Радуйсяmap()
.Надеюсь, это помогло.
Отредактировано 10 ноября 2015: добавлена разработка.
источник
map
функция, но нетforEach
; не могли бы вы просто не использоватьmap
вместоforEach
? С другой стороны, если у языка есть,forEach
но нетmap
, вам придется реализовать свой собственныйmap
. Вы не могли бы просто использоватьforEach
вместоmap
. Скажи мне, что ты думаешь.Вот пример использования Scala в Scala: map возвращает список, foreach ничего не возвращает.
Таким образом, map возвращает список, полученный в результате применения функции f к каждому элементу списка:
Foreach просто применяет f к каждому элементу:
источник
Если вы говорите о Javascript в частности, разница в том, что
map
функцияforEach
итератор.Используйте,
map
если вы хотите применить операцию к каждому члену списка и вернуть результаты в виде нового списка, не затрагивая первоначальный список.Используйте,
forEach
когда вы хотите что- то сделать на основе каждого элемента списка. Вы можете добавлять вещи на страницу, например. По сути, это здорово, когда вам нужны «побочные эффекты».Другие отличия:
forEach
ничего не возвращает (поскольку это действительно функция потока управления), и переданная функция получает ссылки на индекс и весь список, тогда как map возвращает новый список и передает только текущий элемент.источник
ForEach пытается применить функцию, такую как запись в db и т. Д., К каждому элементу СДР, не возвращая ничего обратно.
Но
map()
применяется некоторая функция над элементами rdd и возвращает rdd. Поэтому, когда вы запустите приведенный ниже метод, он не завершится с ошибкой в строке 3, но при сборе rdd после применения foreach он завершится ошибкой и выдаст ошибку, которая говорит:источник