8 ответов:
разные.
foreach перебирает список и применяет некоторые операции с побочными эффектами к каждому члену списка (например, сохранение каждого в базе данных)
map выполняет итерацию по списку, преобразует каждый член этого списка и возвращает другой список того же размера с преобразованными членами (например, преобразование списка строк в верхний регистр)
важное различие между ними заключается в том, что
mapнакапливает все результаты в коллекцию, тогда какforeachничего не возвращает.mapобычно используется, когда вы хотите преобразовать коллекцию элементов с помощью функции, тогда какforeachпросто выполняет действие для каждого элемента.
короче,
foreachпредназначен для применения операции к каждому элементу коллекции элементов, тогда какmapдля преобразования одной коллекции в другую.есть два существенных различия между
foreachиmap.
foreachне имеет концептуальных ограничений на операцию, которую он применяет, кроме, возможно, принятия элемента в качестве аргумента. То есть, операция может ничего не делать, может иметь побочный эффект, может возвращать значение или может не возвращать значение. Всеforeachзаботится о том, чтобы перебирать коллекцию элементов и применять операцию к каждому элементу.
map, С другой стороны, имеет ограничение на операцию: он ожидает, что операция вернет элемент и, вероятно, также примет элемент в качестве аргумента. Элементmapоперация выполняет итерацию по коллекции элементов, применяя операцию к каждому элементу и, наконец, сохраняя результат каждого вызова операции в другие коллекции. Другими словами,mapпреобразование одной коллекции в другую.
foreachработает с одной коллекцией элементов. Это входная коллекция.
mapработает с двумя коллекциями элементов: входной коллекцией и выходной коллекцией.это не ошибка, чтобы связать два алгоритма: в самом деле, вы можете просмотреть два иерархически, где
mapэто специализацияforeach. То есть, вы могли бы использоватьforeachи пусть операция преобразует свой аргумент и вставляет его в другую коллекцию. Итак,foreachалгоритм-это абстракция, обобщение . На самом деле, потому чтоforeachне имеет никаких ограничений на его работу мы можем смело сказать, чтоforeachЭто самый простой механизм зацикливания, и он может делать все, что может сделать цикл.map, а также другие более специализированные алгоритмы, есть ли для выразительности: если вы хотите отобразить (или преобразовать) одну коллекцию в другую, ваше намерение будет более ясным, если вы используетеmapчем если вы используетеforeach.мы можем продолжить эту дискуссию и рассмотреть
copyалгоритм: цикл, который клонирует коллекцию. Этот алгоритм тоже является специализацией . Вы можете определить операцию, которая, учитывая элемент, вставит этот же элемент в другую коллекцию. Если вы используетеforeachс этой операцией вы в действительности выполнилcopyалгоритм, хотя и с уменьшенной ясностью, выразительностью или эксплицитностью. Давайте еще дальше: мы можем сказать, чтоmapспециализацияcopyсама специализацияforeach.mapмая изменить любой из элементов, которые он повторяет. Еслиmapне изменяет ни один из элементов, то это просто скопировал элементов, и с помощью скопировать выразило бы намерение более ясно.в
foreachсам алгоритм может иметь или не иметь возвращаемое значение, в зависимости от языка. В C++, например,foreachвозвращает первоначально полученную операцию. Идея заключается в том, что операция может иметь состояние, и вы можете захотеть, чтобы эта операция вернулась, чтобы проверить, как она развивалась над элементами.mapтоже может возвращать или не возвращать значение. В C++transform(эквивалентmapздесь) возвращает итератор в конец выходного контейнера (коллекции). В Рубин, возвращение значениеmap- это выходная последовательность (коллекция). Таким образом, возвращаемое значение алгоритмов действительно является деталью реализации; их эффект может быть или не быть тем, что они возвращают.
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но поворот приходит, когда вы запускаете следующий код: -
здесь я просто назначил результат возвращаемого значения из карты и 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только ходит через данный массив, так что вы можете делать свои вещи во время ходьбы массива.
наиболее "видимым" отличием является то, что map накапливает результат в новой коллекции, в то время как foreach выполняется только для самого выполнения.
но есть несколько дополнительных предположений: поскольку "цель" map-это новый список значений, на самом деле не имеет значения порядок выполнения. фактически, некоторые среды выполнения генерируют параллельный код или даже вводят некоторые мемуары, чтобы избежать вызова повторяющихся значений или лени, чтобы избежать вызова некоторых из них все.
foreach, с другой стороны, вызывается специально для побочных эффектов; поэтому порядок важен и обычно не может быть распараллелен.
короткий ответ:
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.In Решение 1, если вы просто замените
forEachbymap, решение по-прежнему будет действительным. В решение 2, заменаmapbyforEachсломает ваше ранее рабочее решение.реализация
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: добавлена разработка.
вот пример использования списков в Scala: map возвращает список, foreach ничего не возвращает.
def map(f: Int ⇒ Int): List[Int] def foreach(f: Int ⇒ Unit): UnitSo map возвращает список, полученный в результате применения функции 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
если вы говорите о Javascript в частности, разница в том, что
mapЭто функция цикла в то время какforEach- это итератор.использовать
mapЕсли вы хотите применить операцию к каждому члену списка и получить результаты обратно в виде нового списка, не затрагивая исходный список.использовать
forEachЕсли вы хотите do что-то на основе каждого элемента списка. Например, вы можете добавлять что-то на страницу. По существу, это отлично подходит, когда вы хотите "побочные эффекты".другие отличия:
forEachничего не возвращает (так как это действительно функция потока управления), а переданная функция получает ссылки на индекс и весь список, тогда как map возвращает новый список и передает только текущий элемент.
Comments