[ES6] 데이터컬렉션(4) - Map으로 객체 대신하기

권준혁·2020년 11월 1일
0

javascript

목록 보기
6/19
post-thumbnail

이번 포스팅에서는 Map에 대해 알아보겠습니다.

  • Map은 객체를 대신해 데이터변경이 잦은 키-값 컬렉션에 유용하게 사용할 수 있습니다.
  • Map 객체는 키-값 쌍을 저장하며 각 쌍의 삽입 순서도 기억하는 콜렉션입니다. 아무 값(객체와 원시 값)이라도 키와 값으로 사용할 수 있습니다

Map을 직접 실습해보기에 앞서, 먼저 특징에대해 살펴보겠습니다.
항상 먼저 특징을 살펴보지 않으면 추후에 코딩하면서 기술부채 문제가 발생합니다.

출처 : MDN, Map과 Object의 차이점

차이점이 주제이지만, 사실상 Map의 강점이 더 부각되는 것 같습니다.
Object가 보완된 형태입니다.
다른 차이점도 굉장히 중요하겠지만!
가장 중요한 두가지는 iterable(순회가능) 이라는 점, 추가제거에 유용하다는 점 입니다.
Map에는 맵이터레이터가 내장되어있습니다.
(따라서, Object와 다르게 변환과정없이 for...of문으로 바로 직접순회가 가능합니다.)

또한, 키 동일성에대해서 보게되면 sameValueZero알고리즘에 대한 언급이 있는데,동일성에 대한 것들입니다.
sameValue알고리즘 Object.is()에 관한 문서를 보면 도움이 됩니다.

-0과 +0을 동일시 한다는 점, NaN과 NaN을 동일하게 간주 한다는 것 정도로 이해하고 넘어가겠습니다. 그리고, 깊은비교를 기본으로 하므로 key의 타입도 구별됩니다.


  • 이제 Map의 메서드들이 대해서 알아보겠습니다.
    모든 Map 인스턴스는 Map.prototype을 상속합니다.

게시물에서 메서드 치트시트를 나열하는 것보다 링크를 통해 참조하는게 더 좋을 것같습니다.
출처 : MDN, Map

회원정보를 관리한다고 생각하고 실습해보겠습니다.

const Data = {
    1 : {
        name : 'kwon',
        age : '31',
        gender : 'male'
    },
    2: {
        name : 'doson',
        age : '30',
        gender : 'male'
    },
    3: {
        name : 'kong',
        age : '26',
        gender : 'female'
    }
}

API에서 데이터를 JSON형태로 받아왔다고 가정하겠습니다.

JSON데이터로 Map객체를 생성해보겠습니다.

const entry = Object.entries(Data)
const aMap = new Map(entry)
console.log(aMap)

먼저 첫 줄에 Object.entries()메서드로 2차원 배열로 변환합니다.
초기화 된 entry는 [[key,value],[key,value] ....... ,[key,value]] <- 이런 2차원 배열의 형태를 띄게 됩니다.

맵의 생성자에서 2차원 배열형태로 초기화 할 수 있습니다.
생성된 맵 객체를 로그에 찍어보면

// result
Map {
  '1' => { name: 'kwon', age: '31', gender: 'male' },
  '2' => { name: 'doson', age: '30', gender: 'male' },
  '3' => { name: 'kong', age: '26', gender: 'female' }
}

결과입니다.


이제 여기에 여러가지 메서드를 적용해 본 후
다시 JSON으로 변환해보겠습니다.

먼저 순회하면서 로그에 찍어보겠습니다.
내장 맵이터레이터가 있어 [for...of]문을 사용할 수 있습니다.

for...of문을 사용해보겠습니다.

for(let record of aMap) {
    console.log(record)
}

// result
[ '1', { name: 'kwon', age: '31', gender: 'male' } ]
[ '2', { name: 'doson', age: '30', gender: 'male' } ]
[ '3', { name: 'kong', age: '26', gender: 'female' } ]

forEach문을 사용해보겠습니다.

aMap.forEach((item,key)=>{
    console.log(`${key} : ${item.name}`)
})

// result
1 : kwon
2 : doson
3 : kong

key값을 알고 있는 상태에서 하나의 값을 얻고 싶다면

get()을 사용해보겠습니다.

console.log(aMap.get('1'))

//result
{ name: 'kwon', age: '31', gender: 'male' }

주의할 점 : get()함수의 인수로 문자열을 넣어야합니다 


set(key,value)은 실행 후 해당 맵 객체를 반환합니다

console.log(aMap.set('1',{
    name : 'kwonh',
    age : '31',
    gender : 'male'
}))

// result
Map {
  '1' => { name: 'kwonh', age: '31', gender: 'male' },
  '2' => { name: 'doson', age: '30', gender: 'male' },
  '3' => { name: 'kong', age: '26', gender: 'female' }
}

1번의 name속성이 'kwon'에서 'kwonh'로 set되었습니다. 이 외에 clear(), delete() 등 메소드로 쉽게 수정삭제할 수 있습니다.


iterator 반환 메서드

console.log(aMap.entries())
console.log(aMap.keys())
console.log(aMap.values())

// result
[Map Entries] {
  [ '1', { name: 'kwon', age: '31', gender: 'male' } ],
  [ '2', { name: 'doson', age: '30', gender: 'male' } ],
  [ '3', { name: 'kong', age: '26', gender: 'female' } ]
}
[Map Iterator] { '1', '2', '3' }
[Map Iterator] {
  { name: 'kwon', age: '31', gender: 'male' },
  { name: 'doson', age: '30', gender: 'male' },
  { name: 'kong', age: '26', gender: 'female' }
}

Map객체로 array메서드 사용하기

  • Array.from() 메서드를 이용해 map객체를 array로 변환합니다.
  • 펼침연산자를 이용합니다
const aArray = Array.from(aMap)

Array.from(aMap)으로 유사배열을 배열로 변환한 뒤 aArray에 배열로 초기화 합니다. aArray는 배열메서드를 사용할 수 있습니다.

array로 변환하는 다른 방법으로 펼침연산자를 이용할 수 있습니다.

const modified = [...aMap]

펼침연산자를 이용한 modified도 배열메서드를 사용할 수 있습니다


Map객체에서 JSON 형태로 변환하기

이어서 API통신을 다시 할 수 있도록 reduce()메서드를 이용해
JSON형태의 데이터로 변환해보겠습니다.

const modified = [...aMap]

이 부분부터 이어서하겠습니다.
Map에서 배열로 변환된
modified배열의 형태입니다.

[
  [ '1', { name: 'kwon', age: '31', gender: 'male' } ],
  [ '2', { name: 'doson', age: '30', gender: 'male' } ],
  [ '3', { name: 'kong', age: '26', gender: 'female' } ]
]

reducer를 정의해보겠습니다.

const reducerApplied = modified.reduce((accum,current)=>{
    return {
        ...accum,
        [current[0]]:current[1]
    }
},{})
// result
{
  '1': { name: 'kwon', age: '31', gender: 'male' },
  '2': { name: 'doson', age: '30', gender: 'male' },
  '3': { name: 'kong', age: '26', gender: 'female' }
}

잘 변환 됐습니다. reduce()함수에 대해서는 이전 포스팅을 참고하면 될 것 같습니다.


reduce() 처음에 배울 땐 복잡해서 싫었는데 지금은 즐겨쓰고있습니다.

읽어주셔서 감사합니다

profile
웹 프론트엔드, RN앱 개발자입니다.

0개의 댓글