알고리즘/JavaScript

JavaScript) 자료구조 Map을 활용하기

홍구리당당 2023. 10. 30. 23:13

0. 오늘의 배울 것

Map은 key-value 쌍으로 이루어진 자료구조이다!!

배열은 각 원소에 고유의 인덱스 값을 붙여 순서대로 저장하는 자료 구조이다.

그런데 순서가 중요하지 않은 경우 굳이 배열을 쓰기보단, map을 쓰는 게 더 효율적이다.

List형태의 자료구조들은 순서대로 값을 차곡차곡 저장하는 하나의 줄과 같은 형태지만(ordered), Map 자료구조는 각각의 Key와 매칭 되는 Value을 저장하기 때문에(unordered) 즉 순서보다는 정의된 이름(Key)과 상응하는 데이터들을 묶기 위한 자료 구조로서 효과적이다.

보통 map 자료구조는 hash 함수를 써서 linked list를 활용해 구현되는데, 이 특성 때문에 value 값을 찾거나 삽입, 삭제하는 연산이 빠르다!

1. Map

map은 Key와 Value 쌍으로 이루어진 자료구조이다. js에서는 ES 2015에서부터 등장한 데이터 구조이다.

  • key: 고유한 값, 배열로 따지자면 인덱스 같은 존재. map 안에는 중복되는 key 가 있을 수 없다. 보통 key를 hash 값으로 바꾸어 관리하기 때문이다.
  • value: key와 매칭되는 값, 중복되는 값이 있을 수 있다.

여기서 key와 value가 1대1 대응하는 것을 맵핑(mapping)한다고 한다.

이렇게 key와 value 쌍을 가지는 특성 때문에, Map은 객체와도 비슷하게 보인다.

그렇지만 문자열과 symbol 형만 key(프로퍼티 네임) 로 사용할 수 있는 일반 객체와 다르게, Map 객체는 메소드를 통해 값을 다루기 때문에 다양한 자료형을 key로 활용할 수 있다.

// 일반적인 객체.
const myObj = {
  name : "hong",
  age: 25,
  hobby: "programming:,
};


// map 생성
const myMap = new Map();
myMap.set("name", "hong");
myMap.set("age", 25);
myMap.set(true, "불린형 키에 대한 value");
myMap.set(2023, "숫자형 키에 대한 value");

// key에 대한 value를 가져오려면 get 메소드
console.log(myMap.get(age)); // 25
console.log(myMap.get(true)); // 불린형 키에 대한 value
console.log(myMap.get(2023)); // 숫자형 키에 대한 value 

2. Map의 메소드

Map은 일반 객체와 다르게 키와 밸류에 대해 메소드로 접근한다.

const myMap = new Map();

// key value 쌍 삽입은 set 메소드
myMap.set(2023, '숫자형 key');
myMap.set(true, '불린형 key');


// key에 대한 value 값 참조는 get 메소드
console.log(myMap.get(2023)); // 숫자형 key
console.log(myMap.get(true)); // 불린형 key
console.log(myMap.get("abc")); // 값이 없으면 undefined 반환


// key를 가지고 있는지 확인하려면 has 메소드
console.log(myMap.has(2023)); // true
console.log(myMap.has(123)); // false


// map의 크기를 알려면 size 메소드
console.log(myMap.size); // 2


// map 내부 키 밸류 쌍을 모두 없애려면 clear 메소드
myMap.clear();
console.log(myMap.size); // 0

3. 배열 말고 맵?

굳이 map 자료구조를 써야 할까, 그냥 요소를 찾을 때 for 문으로 배열 내부를 순회해서 찾으면 안될까? 하는 생각이 들 수도 있다.

그런데 map은 시간 복잡도 면에서 굉장히 효율적인 자료 구조이다.

왜냐하면 앞에서 말했듯이, map의 key는 hash table로 관리되기 때문이다. 이 특성때문에 map에서 key를 통해 value를 찾는 탐색 연산이나 삭제, 삽입 연산은 시간 복잡도가 평균적으로 O(1) 이다.
(물론 Collision이 일어날 때 보통 체이닝으로 관리하기 때문에 최악의 경우 O(n)~ 이며, 공간 복잡도가 커질 수는 있다.

그렇지만 배열을 for문으로 순회하는 것보단 시간이 적게 드는 것은 분명하니, 순서가 없는 데이터 모음에서는 map을 쓰는 것을 고려해보자.