티스토리 뷰

1) 배열의 함수형 메소드

for vs forEach

  • 아래 배열을 출력하기 위해 다음과 같이 표현이 가능합니다.

var data = [{title : "hello",content : "간지철철", price : 12000},
            {title : "crong",content : "괜춘한 상품", price : 5500},
            {title : "codesquad",content : "쩌는상품", price : 1200}];

 

// for문을 이용한 방법

for(var i=0; i<data.length; i++) {

  console.log(data[i].title , data[i].price)

}

 

// forEach를 이용한 방법

data.forEach(function(v) {

   console.log(v.title, v.price);

});

<결과>

hello 12000
crong 5500
codesquad 1200

  • forEach는 기존의 for문과 달리 i++이나 length를 판단하는 코드가 필요 없습니다. 그만큼 실수를 줄일 수 있고, 코드는 더 보기 좋습니다.

  • forEach()의 파라미터에 정의한 함수를 넣는데 이 때 정의한 함수를 콜백함수라 합니다.

  • ES6 arrow함수를 사용한다면 참고로 더 간단해집니다.

data.forEach((v)=>console.log(v.title,v.price));

<결과>

hello 12000
crong 5500
codesquad 1200

 

map, filter

  • map메서드는 함수에서 정의한 방법대로 모든 원소를 가공해서 새로운 배열을 반환합니다.

  • 가장 중요한 건 map으로 간단하게 새로운 것들을 원본 배열을 유지한 채 새로운 배열을 만들 수 있다는 점입니다.

arr.map(callback(currentValue[, index[, array]])[, thisArg])

callback: 새로운 배열 요소를 생성하는 함수. 다음 세 가지 인수를 가집니다.
    currentValue: 처리할 현재 요소.
    index(Optional): 처리할 현재 요소의 인덱스.
    array(Optional): map()을 호출한 배열.
thisArg(Optional): callback을 실행할 때 this로 사용되는 값.

return value: 배열의 각 요소에 대해 실행한 callback의 결과를 모은 새로운 배열.

예시)

var filteredData = data.map(function(v) {
    return v.price * 1.1 ;      //10% 가격을 인상!
});

console.log(filteredData);    // [13200.000000000002, 6050.000000000001, 1320]

console.log(data);             //  [{title: "hello", content: "간지철철", price: 12000},
                                        {title: "crong", content: "괜춘한 상품", price: 5500},
                                        {title: "codesquad", content: "쩌는상품", price: 1200}]

 

  • filter메서드는 함수에서 정의한 조건에 맞는 원소만 추려서, 새로운 배열을 반환합니다.

  • 조건은 리턴에서만 적용됩니다.

arr.filter(callback(element[, index[, array]])[, thisArg])

callback: 각 요소를 시험할 함수. true를 반환하면 요소를 유지하고, false를 반환하면 버립니다. 다음 세 가지 매개변수를 받습니다.
    element: 처리할 현재 요소.
    index(Optional): 처리할 현재 요소의 인덱스.
    array(Optional): filter를 호출한 배열.
thisArg(Optional): callback을 실행할 때 this로 사용하는 값.

return value: 테스트를 통과한 요소로 이루어진 새로운 배열. 어떤 요소도 테스트를 통과하지 못했으면 빈 배열을 반환합니다.

예시)

var filteredData = data.filter(function(v) {
    return v.price > 5000;});   // title:codesquad는 price가 1200이라서 조건을 만족하지 못하므로 제외.

console.log(filteredData);     //  [{title: "hello", content: "간지철철", price: 12000},
                                          {title: "crong", content: "괜춘한 상품", price: 5500}]

cf) console.table(filteredData);

 

filter, map을 같이 써보기

  • filter와 map을 동시에 사용하여 다음 요구사항을 구현합니다.
    (요구사항: 숫자가 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;
});
//filteredData//filteredData
0: {title: "hello", content: "간지철철", price: "12,000원"}
1: {title: "crong", content: "괜춘한 상품", price: "5,500원"}
//data
0: {title: "hello", content: "간지철철", price: "12,000원"}
1: {title: "crong", content: "괜춘한 상품", price: "5,500원"}
2: {title: "codesquad", content: "쩌는상품", price: 1200}

 

  • 위의 코드에서는 5,000 이상의 값을 먼저 추출하고, 그리고 정규표현식을 사용해서 ''표현식으로 변경한 배열을 반환했습니다.

  • 그런데, 원래의 배열인 data를 출력해보면 값이 달라져 있습니다. 이처럼 map filter를 체이닝을 하면 원본 데이터도 변합니다.

 

원본 데이터를 유지하자(immutable)

  • 원본 데이터를 유지하기 위해서는 obj 객체를 선언해서 입력하고 반환합니다.
    원래의 data값은 그대로 유지되면서 새로운 배열만 확인할 수가 있습니다.

  • 참고로 이를 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;

});

//filteredData

0:{title: "hello", content: "간지철철", price: "12,000"}

1:{title: "crong", content: "괜춘한 상품", price: "5,500"}

//data

0:{title: "hello", content: "간지철철", price: 12000}

1:{title: "crong", content: "괜춘한 상품", price: 5500}

2:{title: "codesquad", content: "쩌는상품", price: 1200}

 

reduce

  • reduce는 배열의 모든 요소에 대해 지정된 콜백 함수를 호출하며, 콜백 함수의 반환 값을 누적하여 반환하는 함수입니다.
  • reduce 함수의 매개변수로 콜백 함수와 누적을 시작하기 위한 초기 값이며 초기 값은 선택사항입니다.

arr.reduce(callback[, initialValue])

callback: 배열의 각 요소에 대해 실행할 함수. 다음 네 가지 인수를 받습니다.
    accumulator: 누산기(accmulator)는 콜백의 반환값을 누적합니다. 콜백의 이전 반환값 또는, 콜백의 첫 번째 호출이면서 initialValue를 제공한 경우에는 initialValue의 값입니다.
    currentValue: 처리할 현재 요소.
    currentIndex(Optional): 처리할 현재 요소의 인덱스. initialValue를 제공한 경우 0, 아니면 1부터 시작합니다.
    array(Optional): reduce()를 호출한 배열.
initialValue(Optional): callback의 최초 호출에서 첫 번째 인수에 제공하는 값. 초기값을 제공하지 않으면 배열의 첫 번째 요소를 사용합니다. 빈 배열에서 초기값 없이 reduce()를 호출하면 오류가 발생합니다.

return value: 누적 계산의 결과 값.

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

console.log(totalPrice);    // 18700

 

생각해보기

  • 자바스크립트 배열의 메서드 중에 immutable 속성인 메서드는 어떤 것들이 더 있는지 찾아보세요
  • reduce 메서드는 누적된 데이터 처리를 위해서 사용될 수 있습니다.

 

참고자료

[참고링크] map, reduce, filter
https://danmartensen.svbtle.com/javascripts-map-reduce-and-filter

 

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/map

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce

 

Comments