[JavaScript] Hash와 Map

윤후·2022년 6월 7일
3

JavaScript

목록 보기
9/21
post-custom-banner

Hash?


1. 해시 테이블 (Hash Table)

  • 자료구조의 종류 중 하나 (ex. Array, Object 등)
  • key와 value를 가지는 자료구조 형태
  • 배열에서는 key값에 숫자만 가능하지만, Hash Table에서는 문자열 또한 Key (Map에서는 함수도 가능)
  • Hash Function을 통해 빠른 탐색이 가능 -> O(1)

2. 해시 함수 또는 해시 (Hash Function)

  • key와 연결되어 있는 value를 삽입, 삭제, 탐색하는 알고리즘 함수
  • 알고리즘 함수의 종류는 많지만, 대표적으로 MDS 함수가 존재
  • key가 들어오면 Random하게 주소값을 생성한 후, 해당 주소값에 key와 value를 저장
  • 해시함수 과정에서 해시충돌이 일어날 수 있음

해시테이블 : Map


JS에서 해시테이블은 대표적으로 Object, Map, Set이 있다. JS에서 key-value로 이루어진 자료구조는 Object가 대표적이였지만, ES6에서 Map과 Set이 추가되었다.

Map 객체란

  • key-value로 이루어진 해시 테이블
  • 탐색은 get(), 삽입은 set()으로 한다.
  • key는 고유값으로써, 단 한개만 존재한다.
  • key 가능 자료형 : number, string, function, object, NaN

Map Method

  • 생성자
let map = new Map();
  • Map 크기
map.size;
  • 모든 key, value 지우기
map.clear();
  • key로 value 구하기
map.get(key)
  • 특정 key를 가지고 있는지 확인하기
map.has(key)
  • 특정 key로 valur를 map에 넣기 (반환 값은 Map object)
map.set(key, value);
  • [key, value]의 array를 삽입된 순서대로 가진 새로운 lterator 반환
map.entries();

장점


1. 더 많은 key 의 유형

Object의 key는 기호나 문자만을 가질 수 있습니다. 하지만 Map은 어떠한 형태라도 key로 사용될 수 있습니다.

const map = new Map();
const myFunction = () => console.log('I am a useful function.');
const myNumber = 666;
const myObject = {
  name: 'plainObjectValue',
  otherKey: 'otherValue'
};
map.set(myFunction, 'function as a key');
map.set(myNumber, 'number as a key');
map.set(myObject, 'object as a key');

console.log(map.get(myFunction)); // function as a key
console.log(map.get(myNumber)); // number as a key
console.log(map.get(myObject)); // object as a key

2. size 사용 가능

Object의 경우 일반적인 방법으로는 size를 확인 할 수 없습니다. 하지만 Map은 가능하죠.

const map = new Map();
map.set('someKey1', 1);
map.set('someKey2', 1);
...
map.set('someKey100', 1);

console.log(map.size) // 100, Runtime: O(1)

const plainObjMap = {};
plainObjMap['someKey1'] = 1;
plainObjMap['someKey2'] = 1;
...
plainObjMap['someKey100'] = 1;

console.log(Object.keys(plainObjMap).length) // 100, Runtime: O(n)

3. 더 나은 성능

Map은 설계단계부터 데이터의 추가와 제거에 최적화 되어 있기 때문에 성능에 있어서 매우 유리합니다.
맥북프로에서 천만개의 데이터 셋을 가지고 테스트 했을 때 Object는 1.6초의 처리시간이 필요했고 Map은 1ms 이하의 처리시간을 보였습니다.

4. 반복문 사용

Object를 사용하여 반복문을 실행시키려면 불편합니다. 하지만 Map은 반복문을 아주 편리하게 사용 할 수 있어요.

const map = new Map();
map.set('someKey1', 1);
map.set('someKey2', 2);
map.set('someKey3', 3);

for (let [key, value] of map) {
  console.log(`${key} = ${value}`);
}
// someKey1 = 1
// someKey2 = 2
// someKey3 = 3

const plainObjMap = {};
plainObjMap['someKey1'] = 1;
plainObjMap['someKey2'] = 2;
plainObjMap['someKey3'] = 3;

for (let key of Object.keys(plainObjMap)) {
  const value = plainObjMap[key];
  console.log(`${key} = ${value}`);
}
// someKey1 = 1
// someKey2 = 2
// someKey3 = 3

5. 순서의 보장

ECMAScript 2015 이전 버전에서는 Object에서 키의 순서를 보장하지 않습니다.

6. 덮어쓰기 금지

Object에는 미리 정의된 prototype이 있기 때문에 key가 충돌할 위험이 있습니다. 하지만 Map을 사용할 때는 그런 걱정을 할 필요가 없습니다.

const map = new Map();
map.set('someKey1', 1);
map.set('someKey2', 2);
map.set('toString', 3); // No problem for Map

const plainObjMap = new Map();
plainObjMap['someKey1'] = 1;
plainObjMap['someKey2'] = 2;
plainObjMap['toString'] = 3; // Oops, native property

Reference

profile
궁금한걸 찾아보고 공부해 정리해두는 블로그입니다.
post-custom-banner

0개의 댓글