공부는 하면 할수록 모르는 게 많은 것 같다.. 오늘은 자바스크립트의 map 함수에 대해서 공부한 내용을 정리해보려 한다.
-
map() 메서드는 배열 내의 모든 요소 각각에 대해 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환한다.
arr.map(callback(currentValue[, index[, array]])[, thisArg])
- callback: 새로운 배열 요소를 생성하는 함수. 다음의 세가지 인수를 가진다.
- currentValue: 처리할 현재 요소
- index(Optional): 처리할 현재 요소의 인덱스
- array(Optional): map()을 호출한 배열
- thisArg(Optional): Optionalcallback을 실행할 때 this로 사용되는 값
map은 callback 함수를 각각의 요소에 대해 한번씩 순서대로 불러 그 함수의 반환값으로 새로운 배열을 만든다. callback 함수는 (undefined도 포함하여) 배열 값이 들어있는 인덱스에 대해서만 호출된다. 즉, 값이 삭제되거나 아직 값이 할당/정의되지 않은 인덱스에 대해서는 호출되지 않는다.
MDN에 나와있던 설명. 예시를 보면서 좀 더 알아보자.
- array1의 각 요소들을 제곱하기
const array1 = [1, 4, 9, 16];
// pass a function to map
const map1 = array1.map(x => x * 2); //[2, 8, 18, 32]
- 각 요소들의 제곱근을 구해 새로운 배열 만들기
var numbers = [1, 4, 9];
var roots = numbers.map(Math.sqrt);
// roots는 [1, 2, 3]
// numbers는 그대로 [1, 4, 9]
- map을 이용해 배열 속 객체 재구성하기
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}]
- Array안에 Array가 있는 경우
var numbers = [[1,2,3],[4,5,6],[7,8,9]];
var newNumbers = numbers.map(array => array.map(number => number *2));
// [ [ 2, 4, 6 ], [ 8, 10, 12 ], [ 14, 16, 18 ] ]
- + 까다로운 사례
참고: http://www.wirfs-brock.com/allen/posts/166
['1', '2', '3'].map(parseInt);
위의 결과를 [1, 2, 3]으로 생각할 수 있지만 실제 결과는 [1, NaN, NaN]이다. (NaN -> Not a Number)
왜 이런 결과가 나오는 것일까? 이를 알기 위해서는 map과 parseInt의 정의에 대해 제대로 살펴봐야 한다.
parseInt의 정의를 보면 parseInt(string, radix); 임을 알 수 있다. 첫 번째 인자는 string(분석할 값)이고 두 번째 인자는 radix(string이 표현하는 정수를 나타내는 2와 36사이의 진수).
위의 코드와 같이 map함수를 사용할 경우 map은 콜백함수에 세 가지 인자를 전달하게 된다.
parseInt("1", 0, theArray)
parseInt("2", 1, theArray)
parseInt("3", 2, theArray)
그렇다면 위와 같이 실행이 되는데, parseInt는 최대 두 개의 인자를 받기 때문에 세 번째 인자인 theArray를 무시하지만 두 번째 인자는 무시하지 않는다. 따라서 아까와 같은 결과를 얻게되는 것이다. 이를 방지하기 위해서는 아래와 같은 코드를 짜주면 된다.
['1', '2', '3'].map(str => parseInt(str));
// 더 간단하게 해결할 수 있는 방법
['1', '2', '3'].map(Number); // [1, 2, 3]
['1.1', '2.2e2', '3e300'].map(Number); // [1.1, 220, 3e+300]
하지만 Number 라는 더 간단한 방법이 존재한다는 것도 기억하자. 이는 parseInt와 달리 float나 지수표현도 반환한다.
'FE > Javascript' 카테고리의 다른 글
[JS] Array.from을 통한 배열 초기화 (0) | 2021.08.23 |
---|---|
[JS] splice()란? - 배열 요소 추가/삭제/교체 (0) | 2021.08.13 |
[JS] substr(), substring(), slice()란? + 차이점 (0) | 2021.07.26 |
[JS] 배열 정렬 sort() 함수 (0) | 2021.07.14 |
자바스크립트로 난수 맞추는 게임 만들기 (0) | 2021.04.28 |