본문 바로가기

Ecmascript/Javascript

[자료구조] Map과 Set

Map : 중복되지 않은 '키'의 집합

  • 자바의 Map과 특성이 유사한 자료구조
  • 값 가공 메서드 : set(key, value), get(key), has(key), delete(key)

객체 리터럴과의 차이점

  • 임의의 형으로 키를 설정 가능
    • 객체는 프로퍼티로 가능한 요소(문자,숫자)를 키로 하지만 맵은 무엇이든 가능하다.
  • 맵의 사이즈를 취득 가능 -> size() 메서드
    • 열거 가능 : keys()로 모든 키를, values()로 모든 값을, entries()로 모든 키와 값을 취득 할 수 있다.
  • 넣은 순서가 유지된다.
const idols = new Map();
idols.set('외모', '아이린');
idols.set('몸매', '설현');
idols.set('이상형', '연우');

// const idols = new Map([['외모', '아이린'],['몸매', '설현'],['이상형', '연우']]);

console.log(idols.values()); // MapIterator {"아이린", "설현", "연우"}

// for of로 반복
for(let [k, v] of idols) {
  console.log(k, v); 
}
/*
외모 아이린
몸매 설현
이상형 연우
*/

// forEach로 반복
idols.forEach((v, k) => {
    console.log(v, k); 
})
/*
아이린 외모
설현 몸매
연우 이상형
*/

idols.delete('이상형')
console.log(idols.size()) // 2

Map과 Object literal

  • Map은 객체와 같은 key: value 형태이기 때문에 서로 치환해서 코드를 작성하는 것이 가능
const arrInput = [ '3', 'sam 99912222','tom 11122222','harry 12299933','sam','edward','harry' ];
const len = parseInt(arrInput[0]);
/*
위와 같은 배열이 주어졌을때 아래와 같은 로그를 출력해야 하는 경우
sam=99912222
Not found
harry=12299933
*/

Map일 경우

  • 배열을 Map으로 만들기 위해서는 2차원 배열이 필요 [[키:값],[키:값]]
  • Map.has(키)로 키가 있는지 검사 할 수 있고 Map.get(키)로 값을 가져 올 수 있음.
const mapPhonebook = new Map(arrInput.slice(1, len+1).map(v => v.split(" ")));
arrInput.slice(len+1).forEach((name ,i) => {
    if(mapPhonebook.has(name)) {
        console.log(name+"="+mapPhonebook.get(name));
    } else {
        console.log("Not found")
    }
});

객체일 경우

  • 배열을 Map으로 만들기 위해서는 loop가 필요
  • 객체.hasOwnProperty(키)로 키가 있는지 검사 할 수 있고 객체.[키]로 값을 가져 올 수 있음.
const objPhonebook = arrInput.slice(1, len+1).reduce((acc, cur) => {
    const tmp = cur.split(" ");
    acc[tmp[0]] = tmp[1];
    return acc;
}, {});
arrInput.slice(len+1).forEach((name ,i) => {
    if(objPhonebook.hasOwnProperty(name)) {
        console.log(name+"="+objPhonebook[name]);
    } else {
        console.log("Not found")
    }
});

Set : 중복되지 않은 '값'의 집합

  • 자바의 Set과 특성이 유사한 자료구조
  • 키가 없으므로 다이렉트로 접근이 불가능하며 메서드 사용 기준이 값이 된다
  • 값 가공 메서드 : add(value), has(value), delete(value)
  • 객체와 비슷해서 잘 안쓰게 되는 Map과 달리 중복된 값을 거를 때 유용한 자료구조

Map과 공통점

  • 데이터의 사이즈를 취득 가능 -> Setsize 속성, Mapsize()
    • 열거 가능 : values()로 모든 값을, entries()로 모든 키와 값을 취득 할 수 있다.
const nums = new Set();
nums.add('one');
nums.add('two');
nums.add('three');
nums.add('three'); // 중복된 값은 무시됨

console.log(nums.size) // 3 -> 중복 값은 안들어감

for(let v of nums) {
  console.log(v)
}
/*
one
two
three
*/

WeakMap과 WeakSet

  • 키가 참조되지 않으면 GC된다.
  • 키는 참조형이어야 한다.
  • 열거 불가능 하다.