답변:
다른.
foreach는 목록을 반복하고 부작용이있는 일부 작업을 각 목록 멤버에 적용합니다 (예 : 데이터베이스에 각 항목을 저장하는 등).
map은 목록을 반복하고 해당 목록의 각 구성원을 변환하며 변환 된 구성원과 동일한 크기의 다른 목록을 리턴합니다 (예 : 문자열 목록을 대문자로 변환).
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
알고리즘 자체 또는 언어에 따라 반환 값이있을 수도 있고 없을 수도 있습니다. 예를 들어 C ++에서 foreach
원래받은 작업을 반환합니다. 아이디어는 오퍼레이션이 상태를 가질 수 있으며 해당 오퍼레이션이 요소에서 어떻게 진화했는지 점검하기 위해 해당 오퍼레이션을 다시 원할 수 있습니다. map
또한 값을 반환하거나 반환하지 않을 수 있습니다. C ++ transform
( map
여기에 해당)에서는 반복자를 출력 컨테이너 (컬렉션)의 끝으로 반환합니다. Ruby에서의 반환 값은 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
여기에서는 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
그렇지 않습니다. 따라서 map 메소드에 전달 된 콜백 함수 내에서 반환 된 배열을 조작 한 다음 반환 할 수 있습니다.
Array.prototype.forEach
주어진 배열을 통해서만 걸을 수 있으므로 배열을 걷는 동안 물건을 할 수 있습니다.
가장 '가시적 인'차이점은 map이 결과를 새로운 컬렉션에 축적하는 반면 foreach는 실행 자체에 대해서만 수행된다는 것입니다.
그러나 몇 가지 추가 가정이 있습니다. map의 '목적'은 새로운 값 목록이므로 실제로 실행 순서는 중요하지 않습니다. 실제로, 일부 실행 환경은 병렬 코드를 생성하거나 일부 값을 전혀 호출하지 않도록 반복 된 값을 호출하지 않거나 게으름을 피하기 위해 일부 메모리를 도입합니다.
반면에 foreach는 부작용을 위해 특별히 불려집니다. 따라서 순서가 중요하며 일반적으로 병렬화 할 수 없습니다.
짧은 대답 : map
그리고 forEach
다릅니다. 또한 비공식적 map
으로는의 엄격한 상위 집합입니다 forEach
.
긴 대답 : 먼저 forEach
and에 대한 한 줄 설명을 생각해 봅시다 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
?작업 1 과 작업 2map
모두를 해결하는 데 사용할 수 있습니다 . 그러나 태스크 2 를 해결하는 데 사용할 수 없습니다 .forEach
에서 해결 한 당신은 단순히 교체하는 경우 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
존재 하는가?답은 효율성입니다. 배열을 다른 배열로 변환하지 않으려는 경우 왜 변환 된 배열을 계산해야합니까? 그것을 덤프 만? 당연히 아니지! 변환을 원하지 않으면 변환을 수행하지 않아야합니다.
따라서 map을 사용하여 작업 1 을 해결할 수는 있지만 아마 안됩니다. 각각에 대한 올바른 후보입니다.
내가 주로 @madlep의 대답에 동의하는 동안, 나는 그 점을 지적하고 싶습니다 map()
A는 엄격한 슈퍼 세트 의 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()
.
이것이 도움이 되었기를 바랍니다.
2015 년 11 월 10 일 수정 : 정교함이 추가되었습니다.
map
기능이 있지만 그렇지 않은 경우 forEach
; map
대신 대신 사용할 수 없었 forEach
습니까? 반대로, 언어가 forEach
있지만 언어가 없다면 자신의 언어 map
를 구현해야합니다 map
. forEach
대신 대신 사용할 수 없습니다 map
. 네가 어떻게 생각하는지 내게 말해 줘.
다음은 목록을 사용하는 스칼라의 예입니다. map은 list를 반환하고 foreach는 아무것도 반환하지 않습니다.
def map(f: Int ⇒ Int): List[Int]
def foreach(f: Int ⇒ Unit): Unit
따라서 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
특히 자바 스크립트에 대해 이야기한다면 차이점은 map
반복 함수 인 동안 루프 함수 forEach
라는 것입니다.
사용 map
이 목록의 각 구성원에 작업을 적용하고 결과를 원래 목록에 영향을주지 않고, 새로운 목록으로 돌아 가야합니다.
사용 forEach
당신이하고 싶을 때 할 목록의 각 요소에 근거하여 무엇인가를. 예를 들어 페이지에 항목을 추가했을 수 있습니다. 기본적으로 "부작용"을 원할 때 유용합니다.
다른 차이점 : forEach
(실제로 제어 흐름 함수이므로) 아무것도 반환하지 않으며 전달 된 함수는 색인과 전체 목록에 대한 참조를 얻는 반면 map은 새 목록을 반환하고 현재 요소에만 전달합니다.
ForEach는 RDD의 각 요소에 db 등을 쓰는 등의 기능을 되 돌리지 않고 적용하려고합니다.
그러나는 map()
rdd 요소에 일부 함수를 적용하고 rdd를 반환합니다. 따라서 아래 방법을 실행하면 line3에서 실패하지 않지만 foreach를 적용한 후 rdd를 수집하는 동안 실패하고 오류가 발생합니다.
<모듈>의 파일 "<stdin>", 5 행
AttributeError : 'NoneType'개체에 'collect'특성이 없습니다.
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())
Iterator[String]
from을 가져 와서scala.io.Source.fromFile("/home/me/file").getLines()
적용.foreach(s => ptintln(s))
하면 제대로 인쇄되지만 곧 비워집니다. 동시에 적용.map(ptintln(_))
하면 비워지고 아무것도 인쇄되지 않습니다.