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

голоса
199

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

Задан 10/12/2008 в 03:09
источник пользователем
На других языках...                            


9 ответов

голоса
277

Другой.

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

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

Ответил 10/12/2008 в 03:14
источник пользователем

голоса
110

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

Ответил 10/12/2008 в 03:15
источник пользователем

голоса
38

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

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

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

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

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

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

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

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

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

Ответил 28/05/2010 в 22:52
источник пользователем

голоса
30

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не делает. Таким образом , вы можете манипулировать возвращаемый массив внутри функции обратного вызова передается методу карты , а затем вернуть его.

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

Ответил 29/01/2013 в 11:56
источник пользователем

голоса
11

Короткий ответ: 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решение все равно будет действительным. В решении- однако, замена mapна forEachсломает ранее рабочий раствор.

Реализация forEachс точки зрения map:

Другим способом реализации mapпревосходства «s является внедрение 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 «s, я хотел бы отметить, что 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: Добавлена ​​разработка.

Ответил 29/07/2014 в 09:01
источник пользователем

голоса
11

самая «видимая» Разница в том, что карта накапливает результат в новой коллекции, в то время как Еогеасп делается только для самого исполнения.

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

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

Ответил 10/12/2008 в 03:59
источник пользователем

голоса
3

Вот пример в Scala, используя списки: список карт возвращений, 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
Ответил 13/05/2014 в 08:56
источник пользователем

голоса
2

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

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

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

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

Ответил 10/12/2008 в 03:19
источник пользователем

голоса
0

ForEach пытается применить функцию, например, запись в БД и т.д. на каждом элементе ДРР без возвращения ничего обратно.

Но map()применяют некоторые функции над элементами РДА и возвращает RDD. Итак , когда вы запустите метод ниже он не подведет в Line3 , но при сборе ДРРА после применения Foreach он потерпит неудачу , и выдаст ошибку , которая говорит

Файл "<STDIN>", строка 5, в <модуль>

AttributeError: объект «NoneType» не имеет атрибута «собирать»

nums = sc.parallelize([1,2,3,4,5,6,7,8,9,10])
num2 = nums.map(lambda x: x+2)
print ("num2",num2.collect())
num3 = nums.foreach(lambda x : x*x)
print ("num3",num3.collect())
Ответил 11/03/2019 в 13:10
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more