Array.prototype.map()

유선화·2024년 1월 17일

javascript

목록 보기
1/2
post-thumbnail

드디어 map을 정리해 보겠다.

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

Array.prototype.map() - JavaScript | MDN
map() 메서드는 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환합니다.

developer.mozilla.org

mdn을 바탕으로

[
        '거래금액 (만원)',
        '거래면적 (㎡)',
        '거래유형',
        '년',
        '법정동',
        '용도지역',
        '월',
        '일',
        '중개사소재지',
        '지목',
        '지번',
        '지역코드',
        '해제사유발생일',
        '해제여부',
        '구분',
]
[
	{ 
		거래금액 : {#test: '10000'},
		거래면적 : {#test: '300'}, 
		거래유형 : {#test: '직거래'} ,
		
	},
	{ 
		거래금액 : {#test: '10000'},
		거래면적 : {#test: '300'}, 
		거래유형 : {#test: '직거래'} 
	},
]

해당 배열을 토대로 map 객체의 활용을 설명하겠다. 첫번째 배열은 문자열을 가지고 있고 두번째는 전 글에서 소개한 proxy object의 형태를 따 왔다. 배열안에 객체가 있고 객체안에 키와 값이 존재하며 값은 또 다시 키와 값으로 이뤄진 객체가 들어있는 형태이다.

map() 메서드

배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환

구문

arr.map(callback(currentValue[, index[, array]])[, thisArg])
map의 매개변수

callback -> 새로운 배열 요소를 생성한다.

이 콜백함수는 3가지의 인수를 가지는데

currentValue : 처리할 현재 요소,

index : 처리할 현재 요소의 인덱스 ,

array : map을 호출 할 배열,

thisArg : callback을 실행할 때 this로 사용되는 값 을 가진다.

map은 callback 함수를 각각의 요소에 한번씩 불러 함수의 반환값으로 새로운 배열을 만든다.

다음과 같은 예제 코드를 보겠다.
proxyOb는 어떤 api의 헤더값을 불러온 배열을 가지고 있다.

const proxyOb = [
    '거래금액 (만원)',
    '거래면적 (㎡)',
    '거래유형',
    '년',
    '법정동',
    '용도지역',
    '월',
    '일',
    '중개사소재지',
    '지목',
    '지번',
    '지역코드',
    '해제사유발생일',
    '해제여부',
    '구분',
]
const map = proxyOb.map(function(item) {
  let result = item[0]
  return result;
})

map을 콘솔에 찍으면 어떤 값을 반환할까?

리턴값이 바로 생각난다면 map에 대해 잘 이해하고 있다고 본다.

만약 바로 생각나지 않는다면 괜찮다 다음과 같은 과정으로 이해한다면 map에 어떤 콜백함수가 오든 활용이 가능할 것이다.

별로 어렵지 않다.

map함수에서는 각각의 요소를 한번씩 부른다고 했다 즉 proxyOb[0]을 불러온다

proxyOb[0]은 '거래금액 (만원)' 즉 문자열이다. 자바스크립트에서 문자열은 문자의 배열로 취급되므로 item[0]은 proxyOb[0]문자열의 첫 번째 문자인 '거' 를 반환한다.

map 함수는 배열의 모든 요소에 대해 이 작업을 수행하므로, 결과적으로 map에 의해 반환되는 새 배열 map에는 원래 배열 proxyOb의 각 문자열의 첫 번째 문자들이 포함된다.

결과적으로 map 배열에는
['거', '거', '거', '년', '법', '용', '월', '일', '중', '지', '지', '지', '해', '해', '구']
와 같이 각 문자열의 첫 글자만 모아진 배열이 생성된다.

또한 배열 값이 들어있는 인덱스에 대해서만 호출된것도 알 수 있다.

가. map을 활용해 배열 속 객체를 재구성할 수도 있다.

MDN에는 좀 더 간단한 예제로 되어있다.

다음 배열로 좀더 보기 쉽게 키와 값으로만 재구성 해보자


let proxyOb = [
	{ 
		거래금액 : {#test: '10,000'}, 
		거래면적 : {#test: '10'}, 
		거래유형 : {#test: '직거래'} ,
		
	},
	{ 
		거래금액 : {#test: '20,000'}, 
		거래면적 : {#test: '300'}, 
		거래유형 : {#test: '중개거래'} 
	},
]

[{ 거래금액:'10000', ...}] 으로 되어있으면 좋을텐데 배열안에 객체안에 객체가 값으로 들어있다.

최근에 api연동하면서 봤던 배열이다. 나는 map이 아닌 forEach를 활용해 키와 value를 분리해서 원하는 값을 찾아 썼지만 map으로 배열 속 객체를 재구성해 보겠다.

일단 test안에 있는 값을 가져와보자

먼저 제일 간단하게 '10,000' 을 가져와보자

map으로 첫번째 객체 요소에 접근하고 거래금액의 키에 해당하는 값(#test의 값)을 가져오면 된다.

그 후 거래금액:'10000'으로 다시 리턴해야 하니

거래금액이라는 키에 값 item.거래금액['#test']을 매칭한다.

proxyOb.map(function(item){
		  return {	
					거래금액: item.거래금액['#test'],
					거래면적: item.거래면적['#test'],
					거래유형: item.거래유형['#test']
				  }
		});

나. 포괄적으로 사용하기

String에 map을 사용해 각 문자의 아스키 인코딩값의 요소를 배열로 가질 수 있다.

var map = Array.prototype.map;
		var a = map.call("Hello World", function (x) {
		  return x.charCodeAt(0);
		});
// a는 이제 [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]

Hello World라는 문자열이 문자의 배열로 취급되므로 H는 72아스키코드로 반환된다.

const map2 = proxyOb.map(function(item) {
		  let result1 = item.length
		  return result1;
		})

그렇다면 다음 result1의 반환값은?

map2는 proxyOb안의 proxyOb[0]의 문자열 길이가 반환된다.

https://school.programmers.co.kr/learn/courses/30/lessons/120854
다음 프로그래머스의 문제를 map으로 간단하게 풀 수 있다.

다. 까다로운 사례

map 에 하나의 인자만 받는 콜백을 사용한다.

하지만 어떤 함수는 하나의 인자로 호출하지만 2개의 인자를 사용하는 경우도 있다.

["10000", "20000", "30000"].map(parseInt);
// 결과를 [1, 2, 3] 으로 기대할 수 있습니다.
// 그러나 실제 결과는 [1, NaN, NaN] 입니다.

다음은 이렇게 해결한다.

function returnInt(element) {
     return parseInt(element, 10);
}
["1", "2", "3"].map(returnInt); // [1, 2, 3]

여기서 returnInt라는 함수를 호출하는데 이런식으로 함수로 빼 사용하는건 자바스크립트에서 중요한 방법중 하나라고 생각한다.

다음글을 참고해 실제 결과가 [1, NaN, NaN]으로 반환된 이유를 보자 나는 pass

https://medium.com/@toaonly42/%EC%99%9C-javascript-%EB%8A%94-1-7-11-map-parseint-%EB%A5%BC-1-nan-3-%EB%A1%9C-%EB%B3%80%ED%99%98-%ED%95%A0%EA%B9%8C-c4eb373665e6

아까의 proxyOb의 거래금액을 봐본다면 '10,000'이다. 이 값을 정수형으로 바꿔보자

단순히 위에서처럼 parsInt를 사용하면 쉼표 이하는 잘려 10이 출력된다 궁금하면 해보시길

따라서

let arr = ['10,000', '12,000']
arr.map(function(arrInt){
	return parseInt(arrInt.replace(/,/g, ''))
})

replace(/,/g, '')는 문자열 내의 모든 쉼표(,)를 제거한다.

간단히 ,를 제거하면 된다.

다음은 위의 예제처럼 함수를 정의해 작성할 수있다.

//위의 예제에서 처럼 parseInt를 10진수로 변경한 것처럼 문자 ,를 자르는 returnNum함수를 호출한 것이다. 
function returnNum(arrStr){
	return parseInt(arrStr.replace(/,/g, ''))
}
['10,000', '12,000'].map(returnNum)
​

"가" 의 예제 또한 함수를 정의해 작성할 수 있다.

function transformObject(obj) {
  let transformedObj = {};
  for (let key in obj) {
    if (obj[key]['#test']) {
      transformedObj[key] = obj[key]['#test'];
    }
  }
  return transformedObj;
}

const map1 = proxyOb.map(item => transformObject(item));
transformObject함수는 proxyOb[0]객체의 모든 키를 순회하고, 각 키에 대해 '#test' 속성을 가진 값을 찾아 새로운 객체에 할당한다.

이렇게 함수를 사용하는것은 코드의 중복을 줄인다.

가의 예제에서 key값이 한글로 죽 나열되어있는데 만약 key가 10개 30개 이렇게 많다면 코드가 길어질것이다.

const transformedArray = proxyObject.map(item => {
    return {
        거래금액: item.거래금액['#test'],
        거래면적: item.거래면적['#test'],
        거래유형: item.거래유형['#test'],
        구분: item.구분['#text'],
        년: item.년['#text'],
        법정동: item.법정동['#text'],
        용도지역: item.용도지역['#text'],
        월: item.월['#text'],
        일: item.일['#text'],
        중개사소재지: item.중개사소재지['#text'],
        지목: item.지목['#text'],
        지번: item.지번['#text'],
        지역코드: item.지역코드['#text'],
        해제사유발생일: item.해제사유발생일['#text'],
        해제여부: item.해제여부['#text'],
        ...

    };
});

이렇게 말이다.

이상으로 map 함수에 대한 설명을 마치겠다.

profile
좋은게 좋은거다

0개의 댓글