메이쁘

[ES6] 순회에 사용하는 forEach(+ for - in / for - of), filter, map, reduce에 대해 핵심만 짧게 알아보자! 본문

Language/JavaScript

[ES6] 순회에 사용하는 forEach(+ for - in / for - of), filter, map, reduce에 대해 핵심만 짧게 알아보자!

메이쁘 2020. 8. 1. 01:16

안녕하세요.

 

배열의 loop를 위해 ES6 전에는 for, forEach 문을 사용했다면

 

ES6 부터는 filter, map, reduce 함수를 다들 사용하게 되었습니다.

 

 

그러면 각각에 대해 핵심만 알아보겠습니다.

 

*** 예제를 바로 테스트하고 싶다면, F12 - Console 에서 복사-붙여넣기 후 엔터 !

 

 

 

 

 

 

 

forEach()


  -  "실행" 시 사용되는 순회 함수. 로그나 API 호출 시 적합합니다.

 

  -  즉, 배열의 원소를 하나씩 탐색하며 원소를 가지고 어떤 일을 하고자 할 때 사용합니다.

 

  -  밖으로 리턴 값을 줄 수 없습니다. 그래서 내부적으로 값 변경 후 저장하고 싶다면, 별도의 변수를 선언해서 담아야 합니다.

 

  -  ES6 부터는 배열 뿐 아니라 Map, Set 에서도 사용 가능합니다.

 

var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
arr.forEach(ele => {
  console.log(ele);
});


// console 결과
1
2
3
4
5
6
7
8
9
10

  -  배열 변수 명.forEach(배열의 원소 하나의 변수명 => { 실행코드 });

  -  보통 이런 방식으로 코딩하면 됩니다.

 

 

 

 

*** 기존의 for - in, for - of, forEach 의 차이는 무엇일까?

 

  -  for - in 

      ->  Array(배열) 에서는 값을, Object(객체) 에서는 키를 순회합니다.

      ->  하지만, Map과 Set에서는 순회가 불가능합니다.

      ->  내부에서 Enumerable(열거 가능한) 이 true 인 값만 접근 가능하기 때문에, Map과 Set에서는 아무런 값을 얻을 수 없습니다.

      ->  보통 객체의 키들을 얻고자 할 때 사용합니다. (배열 접근을 위해선 굳이 사용하지 않음)

      ->  배열 탐색에 사용할 경우, 첫 번째정해진 순서(인덱스) 대로 탐색하지 않고, 두 번째로는 배열 내 원소 뿐 아니라 해당 배열 변수가 가진 다른 프로퍼티까지 탐색합니다.

 

 

 

 

let obj = {
    one : 1,
    two : 2,
    three : 3
 };

 for(const key in obj) {
   console.log(key, obj[key])
 };
  
  
 // console 결과
 one 1
 two 2
 three 3

  -  for - in 예제.

 

 

 

    -  for - of

        ->  컬렉션 전용 순회.

        ->  [Symbol.iterator] 속성이 있는 모든 컬렉션 요소에 대해 순회 가능합니다.

        ->  그래서, Object(객체) 를 제외한 나머지(Array, Map, Set) 에 사용할 수 있습니다.

        ->  iterator 하는 규칙은 오직 [Symbol.iterator] 속성.

        *** 그래서 새로 추가된 키 - 값 의 값은 for - of 로 얻을 수 없는 것 같습니다.

 

 

// for - of
let arr2 = [1, 2, 3, 4, 5, 6];
arr2["test"] = 7;

for(const key of arr2) {
   console.log(key);
}


// console 결과
1
2
3
4
5
6

  -  새로 추가된 test의 값 7은 출력되지 않습니다.

  -  이미 value로 iterator 순회하기 때문입니다. (틀리면 댓글로 지적해주시면 감사하겠습니다.)

 

 

 

  - forEach, for - in 과 for - of

 

      -  forEach : 속도 빠름. 주로 Array 순회 시 사용. 가독성이 기존 for문보다 높아 주로 사용된다.

      -  for - in : 주로 key를 순회할 때 사용. Array는 값, Object는 키를 순회하며 Map과 Set은 순회 불가능.

      -  for - of : [Symbol.iterator] 속성이 있는 모든 컬렉션 순회 가능. Object를 제외한 나머지 (Array, Map, Set) 에 사용 가능하다.  

 

 

 

 

 

filter()


  -  "테스트" 시 사용되는 순회 함수.

 

  -  특정 조건에 해당하는 원소를 꺼내고 싶을 때 적합합니다.

 

  -  배열 내 모든 원소를 대상으로 사용자가 만든 특정 조건 또는 결과에 부합하는 원소들을 담아 새로운 배열을 만듭니다. (새로 만들어진 배열 리턴)

 

 
// filter
let arr3 = [100, 5, 125, 2362, 12];
let filterArr = arr3.filter(function(x) {
  return x % 5 == 0
});

console.log(filterArr);

// console 결과
[100, 5, 125]


// filter 조건에 맞는 원소가 없으면
let arr3 = [100, 5, 125, 2362, 12];
let filterArr = arr3.filter(function(x) {
  return x % 344 == 2
});

console.log(filterArr);

// console 결과
[]

  -  filter 내부에 함수를 만들어 해당 원소의 조건을 부여한 후 리턴합니다.

 

// filter (ES6. function() 생략 가능)
let arr3 = [100, 5, 125, 2362, 12];
let filterArr = arr3.filter((x) => (x % 5 === 0));
console.log(filterArr);

// console 출력 결과
[100, 5, 125]

  -  ES6 이상 사용 가능한 코드. 람다식으로 생략 가능합니다.

  -  function(원소 변수명) {} 대신 (원소 변수명) => (조건에 따른 리턴 값) 으로 사용해도 됩니다.

 

 

 

map()


  -  "변환" 시 사용되는 순회 함수.

  

  -  각 원소의 값을 변경하여 이전 배열이 아닌 새로운 배열로 다시 만들고 싶을 때 적합합니다.

 

  -  map 사용 시, 무조건 원소의 값을 변경해야 합니다.

 

// map
let arr4 = [5, 10, 15, 20, 25];
let mapArr = arr4.map((x) => (x * 2));
console.log(mapArr);

// console 출력 결과
[10, 20, 30, 40, 50]

  -  위 filter 와 마찬가지로, 람다식으로 생략해서 사용할 수 있습니다.

 

 

 

 

 

 

reduce()


  -  모든 원소(또는 조건을 추가하여, 조건에 맞는 특정 원소) 를 사용하여 하나의 결과를 만들어낼 때 적합합니다.

 

  -  map, filter로 대체할 수 있습니다.

 

 

// reduce
let arr5 = [1, 2, 3, 4];
let reduceArr = arr5.reduce((result, x) => (result = result + x));
console.log(reduceArr);

// console 결과
10

  -  첫 번째 인자는 각 원소를 순회하면서 이전 원소까지 수행한 결과 값 입니다.

  -  즉, 이전 원소에서 계산한 결과가 누적됩니다.

 

 

 

성능 측정 결과


 

각 함수 별 성능 측정 결과 표 (출처 : https://daesuni.github.io/Loop-performance)

 

 

 

위 결과를 놓고 봤을때는 단순 for loop문이 가장 속도가 빠릅니다.

 

하지만, 옛날처럼 속도에 목숨 걸만큼 큰 차이도 나지 않고 아주 미세한 차이일 뿐입니다.

 

 

그래서 그냥

 

forEach, map, filter, reduce를 사용할 기회가 생기면 사용하세요.

 

가독성 측면에서 훨씬 좋습니다.

 

속도 향상 <<<<< 가독성

 

 

코드를 잘읽을 수 있어야 유지보수 / 테스트 가 훨씬 좋아지기 때문입니다.

 

 

감사합니다.

 

 

 

 

참고
https://daesuni.github.io/Loop-performance/
https://blog.ggaman.com/1012
https://n-log.tistory.com/39
https://medium.com/sjk5766/foreach-for-in-for-of-%ED%8A%B9%EC%A7%95-%EB%B0%8F-%EC%84%B1%EB%8A%A5-%EB%B9%84%EA%B5%90-47a77464b034
https://velog.io/@decody/map-%EC%A0%95%EB%A6%AC

 

Comments