JS map()

sookyoung.k·2023년 12월 2일
0

🔰 JavaScript

목록 보기
1/1
post-thumbnail

자바 스크립트, 자바를 처음 배우면서 이미 배우는 개념들이 어렵다는 이유로 '지금 말고 나중에!'를 외치며 외면하다가 결국 만나버렸다. 피한다고 되는 일 하나 없다는 교훈... 그래두 배열 어려워잉...

Array.prototype.map() 공식 문서를 보면서 배운 것도 있고, 실제 코드를 보면서 배운 것들을 정리해보려고 한다. 비공식..? 공식..? 애매하지만 나의 사수인,,, 데(devOps^0^)정현님께 감사⭐


map()

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

    arr.map(callback(currentValue[, index[, array]])[, thisArg])
  1. callback
    map()메서드는 콜백함수를 통해 새로운 배열을 생성하며 다음과 같은 세 가지 인수를 갖는다
  • currentValue: 처리할 현재 요소
  • index: 처리할 현재 요소의 인덱스 (optional)
  • array: map()을 호출한 배열 (optional)
  • thisArg: 콜백함수를 실행할 때 this로 사용되는 값 (optional)
  1. 반환값 → 배열의 각 요소에 대해 실행한 콜백함수의 결과를 모은 새로운 배열

설명

  1. callback 함수를 각각의 요소에 대해 한번씩 순서대로 불러 그 함수의 반환값으로 새로운 배열을 만든다
    * callback함수는 (undefined 포함) 배열 값이 들어있는 인덱스에 대해서만 호출
    → 삭제된 값이나 아직 값이 할당/정의되지 않은 인덱스에 대해서는 호출되지 않는다

map을 호출한 원래 배열의 요소를 순서대로 하나씩 callback 함수에 넣어서 나오는 반환값으로 새로운 배열을 만든다는 의미!!
원본 배열에서 map을 호출하게 되면 인덱스 0번 부터 값을 하나하나 꺼내와서 콜백함수를 실행시키고 그 반환값들을 통해서 새로운 배열을 만드는 것이다.

  1. callback 함수는 호출될 때 대상 요소의 값, 그 요소의 인덱스, 그리고 map을 호출한 원본 배열 3개의 인수를 전달받는다
    • thisArg 매개변수가 map에 전달된 경우 callback 함수의 this값으로 사용된다
    • 그 외의 경우 undefined 값이 this로 사용된다
    • callback 함수에서 최종적으로 볼 수 있는 this 값은 함수 내 this 를 정하는 일반적인 규칙에 따라 결정된다

음... 여긴 뭔 소린지 잘 모르겠다... 어떻게 쓰인다는 건지...? 감이 잘 안 잡힌다.

  1. map은 호출한 배열의 값을 변형하지 않는다
    • 단, callback함수에 의해서 변형될 수는 있다

→ 배열 값은 그대로 가져오면서 값을 추가하거나 콜백함수의 로직에 따라서 내용을 변형할 수 있다(는 이야기 같음)

  1. map이 처리할 요소의 범위는 첫 callback을 호출하기 전에 정해진다
    • map이 시작한 이후 배열에 추가되는 요소들은 callback을 호출하지 않는다
    • 배열에 존재하는 요소들의 값이 바뀐 경우 map이 방문하는 시점의 값이 callback에 전달된다
    • map이 시작되고, 방문하기 전에 삭제된 요소들은 방문하지 않는다
  1. 명세서에 정의된 알고리즘으로 인해 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}]

kvArray라는 배열은 key-value 값으로 이루어진 객체를 담고 있다. (객체 배열)

map을 호출하여 콜백함수를 실행하는데
rObj라는 빈 객체를 선언하고
그 안에 obj로 호출한 kvArraykey 값을 하나씩 호출하여 value를 할당한다. (원본 배열의key값이 속성이 되고 value가 값이 된는 것)
kvArray의 첫 번째 인덱스부터 이를 반복하여 rObj에 넣어준 후 이를 반환한다. 객체를 약간 변형하여 새로 저장!!

var numbers = [1, 4, 9];
var doubles = numbers.map(function (num) {
  return num * 2;
});
// doubles는 이제 [2, 8, 18]
// numbers는 그대로 [1, 4, 9]

numbers라는 배열에서 map을 호출한 뒤 num으로 불러온 numbers 배열의 값을 두 배하여 반환한다.

map은 대충 이렇게 쓰인다... 정도로 정리... 복잡한 for문을 쓰지 않고 배열을 새로 정의하는 방법에 관한 함수인 것 같다.


공식 문서가 약간 이해가 되지 않아서 보충할 수 있는 다른 내용을 찾아봤다.

완전한 map() 메소드 구문

arr.map(function(element, index, array) { }, this);

→ 콜백함수는 각 배열 요소에 대해서 호출된다
map()메소드는 언제나 현재의 element와 그것의 index, 전체 array 객체를 해당 요소에 전달한다. (index, array는 옵셔널한 값)
this는 콜백함수 내부에서 사용된다. 기본적으로는 undefined이지만 다른 값으로 변경할 수도 있다.

let arr = [2, 3, 5, 7]

arr.map(function(element, index, array){
	console.log(this) // 80
}, 80);

this 인수에 숫자 값을 할당했다.

보통은 콜백 함수 내부의 element 인수만 사용한다.


새로운 값을 추가하는 배열 만들기

실제 내가 어떻게 map() 메서드를 사용했는지에 대한 예시이다.

    const noticeInfo: Notice[] = await Notice.findAll({
      where: { mainCategory: '공지사항' },
    });
    const getNoticeInfo = noticeInfo.map((item) => {
      return {
        id: item.id,
        title: item.title,
        mainCategory: item.mainCategory,
        fullDate: item.updatedAt.toISOString().split('T')[0],
      };
    });

noticeInfo라는 배열을 선언한 후, Notice 테이블에서 mainCategory가 '공지사항'인 요소들을 불러온다.

이 배열에 fullDate라는 요소를 추가해야 하기 때문에 map을 호출하였다.
item으로 요소를 하나씩 호출하여 객체를 새로 반환할 것이다.
내가 필요한 것은 idtitle, mainCategory, 그리고 새롭게 추가할 fullDate라는 값이다. 그래서 ...item으로 모든 값을 불러오지 않고 하나씩 뽑아서 가져올 것이다. ...item으로 원본 배열의 모든 것을 호출하면 깔끔하게 안 찍히는 것 같은 너낌...

그래서 getNoticeInfo에는 id값을 원본 배열에서 뽑아온 id 값을 넣어주고, title과 mainCategory에도 반복하여 item으로 원본 배열에서 뽑아온 값들을 넣어준다.

fullDate는 'YYYY-MM-DD' 형식의 날짜 데이터를 'string' 타입으로 가져와야 한다. 떄문에 원본 배열에서 updatedAt을 뽑아온 후 toISOSting()이라는 함수로 Date 타입을 내가 원하는 포맷으로 뽑아온다.

* Date.prototype.toISOString()
toISOString() 메서드는 단순화한 확장 ISO 형식(ISO 8601)의 문자열을 반환합니다. 반환값은 언제나 24글자 또는 27글자(각각 YYYY-MM-DDTHH:mm:ss.sssZ 또는 ±YYYYYY-MM-DDTHH:mm:ss.sssZ)입니다.시간대는 언제나 UTC이며 접미어 Z로 표현합니다.

나는 년-월-일의 형식으로 된 스트링 데이터 변환이 필요한데 단순히 toDateString()이라는 함수를 통해 변환하니까 Wed Oct 05 2011 16:48:00 GMT+0200 (CEST) 이런 형식으로 반환이 되어서 찾아 본 함수이다. toISOString()을 하면 2011-10-05T14:48:00.000Z 이런 형식으로 날짜 데이터를 문자열로 받을 수 있다.

하지만 내가 필요한 것은 날짜 부분의 데이터이기 때문에 split()을 통해서 'T'를 기준으로 잘라준 후 0번째 인덱스인 앞부분 날짜 데이터만 가져와 fullDate라는 값에 넣어준다.

그렇게 내가 필요한 문자열의 날짜 값 fullDate를 포함한 새로운 배열을 만들었다!

거의 다 떠먹여주신 내용... 감사해요 데정현 🤩 !


참고

profile
영차영차 😎

0개의 댓글