최근 배열 위주로 코딩을 많이 해야하는 상황을 접하며 생각보다 모르고 있던 ES5 스펙의 Array 메서드들이 많이 있음을 알게 되었다.
ECMA Script 6 의 새로운 스펙들이 하나둘 최신 브라우저에 적용되고 있는 상황에서 기존 ES5에 이미 구현되어 있는 배열의 메서드들조차도 제대로 파악하고 있지 못한 나 같은 개발자를 위해 for 문으로 돌리기 쉬운 6개의 주요 메서드를 정리해보기로 했다.
Array 객체에서 제공하고 있는, 배열 전체를 돌며 어떤 작업을 할 때 유용한 다양한 메서드들을 지금부터 하나씩 꼼꼼하게 살펴보자. 배열 작업에는 for문이 먼저 생각나는 사람이라면 반드시 읽기를 권한다.
Array.forEach
첫번째로 살펴볼 메서드는 forEach 메서드이다. 배열 전체를 돌며 해당 배열의 요소에 직접 어떤 작업을 수행하고 싶을 때 매우 적합한 메서드이다.
배열 전체를 돌때, 요소마다 콜백 함수를 실행하며 이 콜백함수의 인자는 다른 모든 메서드와 동일한 순서의 인자를 갖는다. 첫번째 인자는 현재 배열 요소의 값이고, 두번째 인자는 현재 배열요소의 위치(index)이며 물론 0부터 시작한다. 세번째 인자는 현재 돌고 있는 배열 자체를 가리킨다.
메서드 수행 후 undefined 를 리턴한다.
아래의 예를 천천히 살펴보면 충분히 forEach 메서드의 사용 방법과 수행 특성을 이해할 수 있다.
//원본 배열 var testArray = ["aaa", "bbb", "ccc", "ddd"]; //배열의 모든 요소에 EDIT라는 문자열을 더하기 //메서드 수행 후 리턴값은 undefined testArray.forEach(function (item, index, array) { array[index] = item + "EDIT"; }); //메서드 수행 후 원본 배열 console.log(testArray); ["aaaEDIT", "bbbEDIT", "cccEDIT", "dddEDIT"]
Array.map
두번째로 살펴볼 메서드는 map 메서드이다. 배열 전체를 돌며 배열값을 사용해서 "또다른 배열"을 만들고 싶을 때 매우 적합한 메서드이다. 원본 배열은 건들지 않고 그 값들만을 사용해서 혹은 약간 변형해서 새로운 배열을 만들어야할 필요가 있을 때 유용하다.
배열 전체를 돌때, 요소마다 콜백 함수를 실행하며 이 콜백함수의 인자는 다른 모든 메서드와 동일한 순서의 인자를 갖는다. 첫번째 인자는 현재 배열 요소의 값이고, 두번째 인자는 현재 배열요소의 위치(index)이며 물론 0부터 시작한다. 세번째 인자는 현재 돌고 있는 배열 자체를 가리킨다.
메서드 수행 후 새로운 배열을 리턴한다.
아래의 예를 천천히 살펴보면 충분히 map 메서드의 사용 방법과 수행 특성을 이해할 수 있다.
//원본 배열 var testArray = ["aaa", "bbb", "ccc", "ddd"]; //배열의 모든 요소에 NEW라는 문자열을 더하기 //메서드 수행 후 리턴값은 새로운 배열 var newArray = testArray.map(function (item, index, array) { return item + "NEW"; }); //메서드 수행 후 원본 배열 console.log(testArray); ["aaa", "bbb", "ccc", "ddd"] //메서드 수행 후 생성된 배열 console.log(newArray); ["aaaNEW", "bbbNEW", "cccNEW", "dddNEW"]
Array.some
세번째로 살펴볼 메서드는 some 메서드이다. 배열 요소 중에서 하나라도 특정 조건을 만족하는지 알고 싶을 때 매우 적합한 메서드이다.
배열 전체를 돌때, 요소마다 콜백 함수를 실행하며 이 콜백함수의 인자는 다른 모든 메서드와 동일한 순서의 인자를 갖는다. 첫번째 인자는 현재 배열 요소의 값이고, 두번째 인자는 현재 배열요소의 위치(index)이며 물론 0부터 시작한다. 세번째 인자는 현재 돌고 있는 배열 자체를 가리킨다.
메서드 수행 중 콜백에서 한번이라도 true 값을 리턴하면 바로 메서드 수행을 중단하고 true를 리턴하며, 전체 요소를 다 돌때까지 콜백에서 true를 리턴하지 않으면 false를 리턴한다.
아래의 예를 천천히 살펴보면 충분히 some 메서드의 사용 방법과 수행 특성을 이해할 수 있다.
//원본 배열 var testArray = ["aaa", "bbb", "ccc", "ddd"]; //배열의 중에서 "bbb"가 있으면 true를 리턴 //메서드 수행 중 true가 리턴되면 메서드 수행을 중단하고 true를 리턴 testArray.some(function (item, index, array) { console.log(index + "번째 요소 : " + item); return !!~item.search("bbb"); }); //로그에 찍히는 내용 //0번째 요소 : aaa //1번째 요소 : bbb //true를 리턴하는 콜백이 있었으므로 리턴값은 true true
Array.every
네번째로 살펴볼 메서드는 every 메서드이다. 배열의 모든 요소가 특정 조건을 만족하는지 알고 싶을 때 매우 적합한 메서드이다.
배열 전체를 돌때, 요소마다 콜백 함수를 실행하며 이 콜백함수의 인자는 다른 모든 메서드와 동일한 순서의 인자를 갖는다. 첫번째 인자는 현재 배열 요소의 값이고, 두번째 인자는 현재 배열요소의 위치(index)이며 물론 0부터 시작한다. 세번째 인자는 현재 돌고 있는 배열 자체를 가리킨다.
메서드 수행 중 콜백에서 한번이라도 false 값을 리턴하면 바로 메서드 수행을 중단하고 false를 리턴하며, 전체 요소를 다 돌때까지 콜백에서 false를 리턴하지 않으면 true를 리턴한다. some 메서드와 유사하지만 반대의 기능을 한다.
아래의 예를 천천히 살펴보면 충분히 every 메서드의 사용 방법과 수행 특성을 이해할 수 있다.
//원본 배열 var testArray = ["aaa", "bbb", "ccc", "ddd"]; //배열의 모든 요소에 "aaa"가 있으면 true를 리턴 //메서드 수행 중 false가 리턴되면 메서드 수행을 중단하고 false를 리턴 testArray.every(function (item, index, array) { console.log(index + "번째 요소 : " + item); return !!~item.search("aaa"); }); //로그에 찍히는 내용 //0번째 요소 : aaa //1번째 요소 : bbb //false를 리턴하는 콜백이 있었으므로 리턴값은 false false
위의 예제에서는 모든 요소에 aaa 가 포함되어 있는지를 체크했는데, 당연히 두번째 요소가 bbb 이므로 그 시점에서 메서드가 종료되고 false 를 리턴하는 것을 볼 수 있다.
이번에는 모든 요소를 만족하는 경우를 살펴보자.
//원본 배열 var testArray = ["aaa", "bbb", "ccc", "ddd"]; //배열의 모든 요소가 알파벳 소문자로 이루어져 있으면 true를 리턴 //메서드 수행 중 false가 리턴되면 메서드 수행을 중단하고 false를 리턴 testArray.every(function (item, index, array) { console.log(index + "번째 요소 : " + item); return !!~item.search(/[a-z]+/); }); //로그에 찍히는 내용 //0번째 요소 : aaa //1번째 요소 : bbb //2번째 요소 : ccc //3번째 요소 : ddd //콜백이 모두 true를 리턴하므로 리턴값은 true true
Array.filter
다섯번째로 살펴볼 메서드는 filter 메서드이다. 배열에서 특정 케이스만 필터링해 추출해서 새로운 배열로 만들고 싶을 때 매우 적합한 메서드이다.
배열 전체를 돌때, 요소마다 콜백 함수를 실행하며 이 콜백함수의 인자는 다른 모든 메서드와 동일한 순서의 인자를 갖는다. 첫번째 인자는 현재 배열 요소의 값이고, 두번째 인자는 현재 배열요소의 위치(index)이며 물론 0부터 시작한다. 세번째 인자는 현재 돌고 있는 배열 자체를 가리킨다.
메서드 수행 중 콜백에서 true를 리턴하는 경우 해당 배열 요소를 추출해서 새로운 배열에 추가하고, 메서드가 종료될 때 이렇게 추출된 배열 요소만으로 이루어진 새로운 배열을 리턴한다.
아래의 예를 천천히 살펴보면 충분히 filter 메서드의 사용 방법과 수행 특성을 이해할 수 있다.
//원본 배열 var testArray = ["aaa", "bbb", "ccc", "ddd"]; //배열의 요소가 a 또는 b로 이루어져 있으면 추출 //메서드가 종료되면 추출된 요소로만 이루어진 새로운 배열을 리턴 var newArray = testArray.filter(function (item, index, array) { return !!~item.search(/[ab]+/); }); //메서드 수행 후 원본 배열 console.log(testArray); ["aaa", "bbb", "ccc", "ddd"] //메서드 수행 후 생성된 배열 console.log(newArray); ["aaa", "bbb"]
Array.reduce
여섯번째로 살펴볼 메서드는 reduce 메서드이다. 배열의 요소들을 하나씩 돌며, 이전 콜백의 리턴값을 previous item 으로 넘겨받아 어떤 작업을 수행하고 싶을 때 매우 적합한 메서드이다.
다른 메서드와는 약간 다른 형태를 띄고 있기 때문에 사용하기 까다롭다고 느낄 수 있지만, 이해하고 나면 Promise를 활용한 비동기 작업의 순차적 실행 등에 이용하는 등 상당히 유용한 메서드이다.
배열 전체를 돌때, 요소마다 콜백 함수를 실행하며 이 콜백함수의 인자는 다른 모든 메서드와 조금 다른 인자를 갖는다. 첫번째 인자는 이전 콜백 함수에서 리턴한 값이고, 두번째 인자는 현재 배열 요소의 값이고, 세번째 인자는 현재 배열요소의 위치(index)이며 물론 0부터 시작한다. 네번째 인자는 현재 돌고 있는 배열 자체를 가리킨다.
그리고 다른 메서드와는 달리 콜백 함수 뒤에 인자를 하나 더 줄 수 있는데, 이 인자는 첫 콜백함수에 previousItem 으로 주입될 값이다.
아래의 예를 천천히 살펴보면 충분히 reduce 메서드의 사용 방법과 수행 특성을 이해할 수 있다.
//원본 배열 var testArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; //각 콜백마다의 리턴값을 previousItem 으로 넘겨받아 어떤 작업을 수행 //메서드가 종료되면 마지막 콜백의 리턴값을 리턴 var result = testArray.reduce(function (previousItem, currentItem, index, array) { //반환된 결과는 다음번 콜백의 첫번째 파라메터로 다시 전달된다. return previousItem + currentItem; }, 0); //메서드 수행 후 원본 배열 console.log(testArray); [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] //메서드 수행 후 리턴값은 0부터 10까지의 합 console.log(result); 55
마치며
지금까지 Array 객체에서 기본적으로 제공하고 있는 메서드들 중 잘 알려지지 않은, (내가) 최근 유용하게 사용하게 된 주요 Array 객체의 메서드들에 대해 알아보았다.
지금까지 설펴본 메서드들은 모두 동기적으로 동작하기 때문에 이러한 특성을 응용해서 기존에 for 문으로 처리하던 부분을 좀더 깔끔하게 처리하거나 응용할 수 있을 것으로 보인다. 또 reduce 메서드의 경우 비동기 작업에서 Promise와 함께 응용하면, 비동기 작업을 순차적으로 수행하는데 활용할 수도 있다. 이 부분에 대해서는 차후 포스팅을 통해 소개하고자 한다.
이미 알고 있던 사람에게는 다시 한번 정리하는 시간이, 모르고 있던 사람에게는 좀더 새로운 안목을 갖게되는 시간이 되었기를 기대한다.
참고
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array