[Javascript] Map, Set

merkyuri·2022년 5월 10일
0

Javascript

목록 보기
1/2
post-thumbnail

Java에서는 배열을 사용하다가 생기는 비효율적인 문제를 해결하기 위해서 자료구조를 사용하기 위한 “컬렉션 프레임워크"라는 개념이 있다.

Javascript에서도 객체와 배열만으로 해결하기 힘든 부분들을 위해서 MapSet 이 등장하였다.


Map이란?

: 데이터와 키를 같이 저장할 수 있는 자료구조이다.


주요 메서드와 프로퍼티 :

new Map() // map을 만든다
map.set(key, value) // key를 이용해 value를 저장한다
map.get(key) // key에 해당하는 값 반환. key가 존재하지 않다면 undefined를 반환
map.has(key) // key가 존재하면 true, 아니면 false를 반환
map.delete(key) // key에 해당하는 값 삭제
map.clear() // map 안의 모든 요소 제거
map.size // 요소의 개수 반환

map.keys() // 각 요소의 키를 모아둔 iterable 객체를 반환
map.values() // 각 요소의 값을 모은 iterable 객체를 반환
map.entries() // 요소의 [key, value] 한 쌍으로 하는 iterable 객체 반환. 이 객체는 for...of 루프의 기초로 쓰인다

다음과 같은 특징이 있다

  • Key-value의 한 쌍으로 이루어진 데이터 집합이다.
  • 본래 key 삽입 순서를 기억한다
  • 어떤 value(객체와 원시값*)든 key 혹은 value로 사용될 수 있다 (key의 타임에 제약이 없음)
  • 순서는 유지되지 않는다
  • 삽입 순서로 요소를 반복한다. 루프는 각 반복에 대해 for...of 루프의 [key, value] 배열을 반환한다
  • Key에는 중복된 값이 입력될 수 없다
  • Value에는 중복이 허용된다
  • NaN 도 key로 쓸 수 있다

❗ Key equality는 sameValueZero 알고리즘을 기반으로 한다

❗ 뛰어난 검색 속도를 가지고 있다는 장점이 있다

❗ 인덱스가 따로 존재하지 않아서 iterator를 사용한다




Set이란?

: 중복이 존재할 수 없는 자료구조이다. 어떤 값이라도 그 Set 콜렉션 내에서 유일하다


주요 메서드:

new Set(iterable) // set을 만든다. iterable 객체를 전달받으면(대게 배열) 그 안의 값을 복사해서 set에 넣어준다
set.add(value) // value를 추가하고 set 자신을 반환
set.delete(value) // value 제거. 호출 시점에 set 내에 value가 있어서 제거에 성공하면 true, 아니라면 false를 반환
set.has(value) // set 내에 값이 존재하면 true, 아니면 false
set.clear() // set 비우기
set.size // set에 몇 개의 값이 있는지 count

set.keys() // set 내의 모든 값을 포함하는 iterable 객체 반환
set.values() // set.keys와 동일한 작업을 한다. map과의 호환성을 위해 만들어진 메서드
set.entries() // set 내의 각 값을 이용해서 만든 [value, value] 배열을 포함하는 iterable 객체 반환. map과의 호환성을 위해 만들어졌다

다음과 같은 특징이 있다

  • 모든 값들은 고유해서 새로운 값을 추가하거나 변경하면 값 비교가 이루어진다
  • 인덱스를 사용하지 않는다
  • 인덱스 매개변수가 없다
  • 집합에 빗대어 생각할 수 있다
  • 원시값과 객체 참조 모두 유일한 값을 저장할 수 있다
  • 삽입 순서대로 요소를 순회한다
  • NaNundefinedSet 에 저장할 수 있다

❗ 조회에 있어서 Array 에 비해 훨씬 빠르다

Array 는 배열, 무언가를 나열할 수 있기 때문에 다양한 타입이 오기도 하고 중복되는 같은 값이 올 수 있다. Set 은 중복되지 않은 값들을 모아둔 집합이다. 여러개의 값들을 나열한 Array 와 그 중에서 중복된 것들을 제거한 것이 Set 이기 때문에 조회에 있어서 훨씬 빠르다고 할 수 있다.

❗ (Map과 마찬가지로) 인덱스가 따로 존재하지 않기 때문에 iterator를 사용한다

Set 의 value에 반복 작업 하기 위해서 for...offorEach 를 사용한다. 이 때 forEach 를 사용하려면,

set.forEach((value, valueAgain, set) => {
	alert(value);
});

와 같이 사용하게 되는데 forEach 에 쓰인 콜백 함수의 세 개의 인수 중 첫 번째 값과 두 번째 값은 동일한 값이다. 이렇게 구현된 이유는 map 과의 호환성 때문이다. 따라서 map 과의 호환성을 띄고 있기 때문에 mapset 으로 혹은 setmap 으로 교체하기가 쉽다.




WeakMap & WeakSet

자바스크립트는 추후 사용될 가능성이 있는 값을 메모리에 유지한다(garbage collection 참고). 객체의 프로퍼티나 배열의 요소, map 이나 set 을 구성하는 요소, 즉 자료구조를 구성하는 요소도 자신이 속한 자료구조가 메모리에 남아있는 동안 도달 가능한 값으로 취급되어 메모리에서 삭제되지 않는다.

그러나 WeakMap 을 사용하면 키로 쓰인 객체가 garbage collection의 대상이 된다.

WeakMap

Map 과의 차이 :

  • 키를 약하게 참조하는 key-value pair
  • 키로 오직 Object 타입만 사용할 수 있다. 원시값은 불가능
  • WeakMap 의 key 로 사용된 객체를 참조하는 것이 아무것도 없다면 해당 객체는 메모리와 WeakMap 에서 자동으로 삭제된다
  • 반복 작업(iterable)을 지원하지 않음
  • keys(), values(), entries() 메서드를 지원하지 않는다. 따라서 key 나 value 전체를 얻는게 불가능하다
// WeakMap이 지원하는 메서드
weakMap.get(key)
weakMap.set(key, value)
weakMap.delete(key)
weakMap.has(key)

적은 메서드만 제공하는 이유: Garbage collection이 정확히 일어나는 시점을 알 수 없으므로 요소(key, value) 전체를 대상으로 무언가를 하는 메서드는 동작 자체가 불가능하다.

WeakSet

Set 과의 차이 :

  • Object 만 저장할 수 있다. 원시값은 저장할 수 없다
  • Set 안의 객체는 도달 가능할 때만 메모리에서 유지된다
  • add, has, delete 를 사용할 수 있고 size, keys() 나 반복 작업 관련 메서드는 사용할 수 없다

WeakMapWeakSet 의 가장 큰 단점은 iterable 하지 않다는 점이다. 저장된 자료를 한번에 얻는게 불가능하다. 그래서 객체와 함께 추가 데이터를 저장하는 용도로 쓸 수 있다.

MapSet에 반복 작업을 할 때, 해당 컬렉션에 요소나 값을 추가한 순서대로 반복 작업이 이루어진다. 이 두 컬렉션은 정렬이 되어있지 않다고 할 수 없으나 요소나 값을 재 정렬 하거나 (배열에서 인덱스를 이용해서 요소를 가져오는 것처럼) 숫자를 이용해 특정 요소나 값을 가지고 오는 것은 불가능하다.





*원시값: 객체가 아니면서 메서드도 가지지 않는 데이터. 7 종류가 존재하는데 string, number, bigint, boolean, undefined, symbol, 그리고 null 이 존재한다. 모든 원시 값은 불변하기 때문에 변형시킬 수 없다.


References :
코어 자바스크립트 맵과 셋
코어 자바스크립트 위크맵과 위크셋
키기반의 컬렉션
Javascript Set 그리고 Map

profile
냥발자가 되자

0개의 댓글