본문 바로가기

Javascript/Javascript(ES6)

자바스크립트에서 제공하는 배열(Array)의 유용한 함수 (reduce, map, filter, indexOf, foreach)

반응형

자바스크립트(javascript)에서 제공하는 배열의 함수

ES6에서만 사용하는 것은 아니지만 자바스크립트 프로그래밍할 때 유용한 메서드이면서 다른 사람의 코드를 보면서 이해를 못했던 필자 같은 사람을 위해 정리한다.


(1) 배열 안의 특정값 찾기 ( indexOf )

배열에서 특정 값이 존재하는지 탐색할 때 for문으로 일일이 검사하면서 코드를 짜는게 보통이다.

1
2
3
4
5
6
var isExist = false;
for(var i = 0 ; i<arr.length ; i++){
    if(arr[i] === "특정값"){
        isExist = true;
    }
}


이렇게 수고스럽게 하지말고 indexOf 연산으로 찾아보자. (특정 값이 처음 나오는 인덱스를 리턴함)

lastIndexOf()함수도 있는데 특정 값이 마지막으로 나오는 인덱스를 리턴한다.

1
var isExist = (arr.indexOf("특정값")!== -1)


한 줄로 해결 가능하다. 

* 참고로 문자열에도 indexOf()를 사용할 수 있다. ( "123456".indexOf("567"); )

그러나 문자열은 보통 정규표현식이 가능한 match() 메서드를 이용하는 것이 바람직하다.


(2) 배열, JSON 오브젝트에서 필터링하기 ( filter )

기본 구문

var new_array = arr.filter(callback[, thisArg]) - thisArg는 각 filter콜백메서드안에서 this로 사용될 값 지정

callback메서드는 배열의 각 요소에 대해 테스트하는 함수

1
2
3
4
5
function isBigEnough(value) {
  return value >= 10;
}
var filtered = [125813044].filter(isBigEnough);
// filtered 는 [12, 130, 44]


배열에 대해서 filter를 적용해 10이상인 값만 필터링하는 예제

1
2
3
4
5
6
7
8
9
10
var arr = [    
  {"name":"apple""count"2},    
  {"name":"orange""count"5},    
  {"name":"pear""count"3},    
  {"name":"orange""count"16}
];    
var newArr = arr.filter(function(item){    
  return item.name === "orange";
});  
console.log("Filter results:",newArr);


JSON에서 객체중에 name속성이 orange인 것 필터링하는 예제

여기서는 item이라는 이름으로 callback메서드의 매개변수를 받았다.

callback메서드는 순서대로 기본적으로 (element, index, array)를 받을 수 있다. (값, 인덱스, 기존 배열)

ES6 arrow function쓰면 깔끔하게 나오겠다.


(3) 배열 각 요소에 지정된 작업 수행 ( forEach )

기본 구문

array1.forEach(callback[, thisArg]) - thisArg는 this로 지정될 값 선택사항으로 지정.

callback메서드는 각 요소에 지정된 작업을 수행할 메서드

argument로 순서대로 callback(value, index, array1)을 가질 수 있다. (값, 인덱스, 기존배열)

1
2
3
4
5
6
7
8
9
10
function logArrayElements(element, index, array) {
  console.log('a[' + index + '] = ' + element);
}
// 인덱스 2는 배열의 그 위치에 항목이 없기에
// 건너뜀을 주의하세요.
[25, , 9].forEach(logArrayElements);
// 기록:
// a[0] = 2
// a[1] = 5
// a[3] = 9


filter와 비슷하게 사용 가능

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function Counter() {
  this.sum = 0;
  this.count = 0;
}
Counter.prototype.add = function(array) {
  array.forEach(function(entry) {
    this.sum += entry;
    ++this.count;
  }, this);
  // ^ 마지막 this주의 callback메서드에서 this를 사용하기 위해서
  // this를 넘겨주는 모습임.
};
 
var obj = new Counter();
obj.add([259]);
obj.count
// 3
obj.sum
// 16


thisArg 쓰는 부분 주의할 것.


(4) 배열의 모든 요소 각각에 제공된 함수를 호출하고 결과를 모아 새로운 배열반환 ( map )

* 포인트는 같은 길이의 새로운 배열을 반환한다는 점임. 같은 크기의 배열이 굳이 필요없는 상황이면 forEach가 적절
* forEach와의 차이점은 map은 각 루프에서 return을 할 수 있음.

기본 구문

arr.map(callback[, thisArg]) - thisArg는 역시 this를 넘겨주기용

callback 메서드의 파라미터 callback(currentValue, index, array) (현재처리되고 있는 요소, 현재 인덱스, 기존 배열)

1
2
3
var numbers = [149];
var roots = numbers.map(Math.sqrt);
// roots의 값은 [1, 2, 3]이 되지만, numbers는 그대로 [1, 4, 9]


Math.sqrt 는 제곱근을 구하는 함수

1
2
3
4
5
6
7
8
var kvArray = [{key:1, value:10}, {key:2, value:20}, {key:3, value: 30}];
var reformattedArray = kvArray.map(function(obj){ 
   var rObj = {};
   rObj[obj.key] = obj.value;
   return rObj;
});
// reformattedArray는 [{1:10}, {2:20}, {3:30}]가 되지만, 
// kvArray는 여전히 [{key:1, value:10}, {key:2, value:20}, {key:3, value: 30}]


결과 값이 기존 배열과 같은 크기임을 유념.


(5) 배열에서 누적 계산값이 필요할 때 ( reduce )

조금 생소하다.

reduce는 왼쪽에서 오른쪽으로 이동하며 배열의 각 요소마다 누적 계산값과 함께 함수를 적용해 하나의 값으로 만든다.

기본 구문

reduce(callback[, initialValue])

callback(accumulator, currentValue, currentIndex, array) (콜백이 반환하는 값 누적시킨 변수, 값, 인덱스, 기존배열)

* 처음 reduce가 시작될 때 initialValue 또는 accumulator 둘 중 하나의 값을 가질 수 있다.

즉, accumulator는 initialValue와 같고 currentValue는 배열의 첫번째 값과 같다.

만약 initialValue가 없으면 accumulator는 배열의 첫번째 값과 같고 currentValue는 두번째와 같다.

=> initialValue가 있냐 없냐에 따라 다소 이상해 보일 수 있으니 반드시 참고해야 함.

1
[01234].reduce( (prev, curr) => prev + curr );


ES6에서 이런식으로 작성가능한데 prev가 accumulator임. 결국 다 더하는 sum임 return을 반드시해서 다음 accumulator를 줘야함.

1
2
3
[01234].reduce(function(accumulator, currentValue, currentIndex, array) {
  return accumulator + currentValue;
}, 10);


제일 뒤에 10이라는 initialValue가 있으니 초기에 accumulator는 10 즉 결과적으로 마지막에 20 리턴;

다소 어려움.....

참고 사이트 :

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

http://blog.kazikai.net/?p=16

모질라 개발자사이트에서 대부분 참고하였습니다.

반응형