[Web] javascript for vs forEach

for문을 써도 대부분의 반복 작업은 어려움 없이 할 수 있다. 하지만 자바스크립트에는 다른 여럭 메서드들이 존재하고 이를 잘 활용하면 for문 없이도 간단히 코드를 짤 수 있다.

var data = [{title : "hello",content : "간지철철", price : 12000},
            {title : "crong",content : "괜춘한 상품", price : 5500},
            {title : "codesquad",content : "쩌는상품", price : 1200}];
cs
위 데이터를 놓고 실험해보자.

1. forEach
for(var i=0; i<data.length; i++) {
  console.log(data[i].title , data[i].price)
}
data.forEach(function(v) {
   console.log(v.title, v.price);
});
cs
data 내부 값을 출력하는 코드다.  위 for문을 보면 반복을 수행하기 위해 'i'를 새로 선언 하고있다. 하지만 forEach를 사용하면 function 을 인자로 받아 다른 변수의 선언이 불필요하고 간결하게 만들 수 있다.

2. map / filter

var mappedData = data.map(function(v) {
    return v.price * 10 ; //10배로 가격을 인상!
});
cs
map 메서드는 함수에서 정의한 방법대로 모든 원소를 가공해서 원본 데이터를 변화시키지 않고 새로운 배열을 반환한다. 위 코드는 data에서 가격을 10배 인상하는 코드이다. 결과 데이터를 보면 10이 곱해진 price만 들어있는 배열이 들어온다.
price뿐 아니라 모든 데이터를 가진 원본 데이터 형식의 새로운 데이터 배열을 만들고 싶다면 새로운 배열을 만들고 값을 넣어 반환하게 해야 한다.

var newData = data.map(function(v) {
    var obj= {name:v.title, content:v.content, price: v.price*10};
    return obj;
});
cs

var filteredData = data.filter(function(v) {
    return v.price > 5000;  //5000원이상만 추출
});
cs
filter 메서드는 함수에서 정의한 조건에 맞는 원소만 추려서 해당 원소만 가진 새로운 배열을 반환하는 '필터'같은 메서드다. map 메서드와 달리 if 문 처럼 동작하면서 필터를 거친 데이터는 전부 반환한다.

3. 복합
var filteredData = data.filter(function(v) {
  return v.price > 5000;
}).map(function(v) {
  v.price = (''+v.price).replace(/^(\d+)(\d{3})$/"$1,$2원");
  return v;
});
cs
filter와 map 메서드를 함께 사용하여 5000원이 넘는 데이터의 가격은 1000단위로 ','를 표시하고 뒤에 단위를 '원'으로 표시하는 코드이다. 그런데 이 작업을 수행하고 원본 데이터를 출력해보면 데이터가 수정 되어있다. 

4. immutable
원본 데이터가 변경되면 추적도 어렵고 어디서 어떤 이유로 변경된 것인지 알아내기 어렵다. 원본 데이터를 유지하는 속성을 immutable하다고 표현한다.
위의 코드에서 임시 배열 var obj를 선언해 작업 결과를 저장하고 반환하면 원본 데이터가 유지되어 immutable하다 부를 수 있다.

var filteredData = data.filter(function(v) {
    return v.price > 5000;
}).map(function(v) {
  var obj = {};
  obj.title = v.title;
  obj.content = v.content;
  obj.price = (''+v.price).replace(/^(\d+)(\d{3})$/"$1,$2원");
  return obj;
});
cs

5. reduce
배열의 모든 요소에 대해 지정된 콜백 함수를 호출하며 콜백 함수의 반환 값을 누적하여 반환하는 함수이다. reduce 함수는 매개변수로 콜백 함수와 누적을 시작하기 위한 초기 값을 받으며 초기 값은 선택사항이다. (디폴드 값은 0)

var totalPrice = data.reduce(function(prevValue, product) { return prevValue + product.price; }, 0);
console.log(totalPrice);
cs

위 코드를 실행해보면 모든 상품의 가격을 더해 출력하는 결과가 나온다.
 콜백 함수 (reducer)는 4개의 인자를 가진다.

  1. 누산기(acc) : 콜백의 반환값을 누적한다. 콜백함수의 이전 반환값 또는 초기값을 설정한 경우 설정한 초기값이 들어간다.
  2. 현재값(cur)
  3. 현재 인데스(idx)
  4. 원본 배열(src)
Arrow function을 사용해 아래와 같이 나타낼 수도 있다.


const array1 = [1234];
const reducer = (accumulator, currentValue) => accumulator + currentValue;
 
// 1 + 2 + 3 + 4
console.log(array1.reduce(reducer));
// expected output: 10
cs



성능만 따지고 본다면 for문이 더 나을지도 모른다. 하지만 map, reduce, filter와 같은 메서드들을 잘 사용하면 더 가독성 좋고, 덜 복잡하 코드를 짤 수 있어 넓게 봤을 때 효율성이 어떤 메서드에서 나올지 생각해보고 코드를 작성하는 것이 중요하다. 


No comments:

Powered by Blogger.