Map은 키(key) - 값(value) 쌍을 저장하는 내장 객체
| 특징 | Map | 일반 객체 {} |
|---|---|---|
| 키 타입 | 모든 자료형 가능 (객체 포함) | 문자열, 심볼만 가능 |
| 키 순서 | 입력 순서 유지 | 보장되지 않음 |
| 접근 방법 | map.get(key) / map.set(key, val) | obj[key] 또는 obj.key |
| 키 존재 확인 | map.has(key) | key in obj 또는 obj.hasOwnProperty(key) |
| 크기 확인 | map.size | 직접 계산 (Object.keys(obj).length) |
순서에 대해 조금 더 자세히 말해보자면
요즘 대부분의 JS 엔진은 삽입 순서대로 출력한다.
하지만! Object는 명확하게 순서를 보장하지는 않음
특히 숫자형 키를 쓰면 순서가 자동 정렬되기도 함const obj = {}; obj[2] = 'two'; obj[1] = 'one'; console.log(obj); // { '1': 'one', '2': 'two' } ← 숫자 키는 정렬됨!만약 순서를 보장하고싶다면 Map 사용을 권장.
Map은 입력한 순서를 반드시 유지
숫자 키를 써도 절대 정렬되지 않음
값에 접근
Map은 .get()과 .set()만 사용해야 하며, []로는 값에 접근할 수 없음
Object는 [] 또는 .로 접근 가능하며, 숫자 키는 자동으로 문자열로 변환됨let map = new Map(); map.set(1, 'one'); console.log(map.get(1)); // "one" console.log(map[1]); // undefinedlet obj = {}; obj[1] = 'one'; // 숫자 → 문자열 '1' console.log(obj[1]); // "one" console.log(obj['1']); // "one"
| 메서드 | 설명 |
|---|---|
| new Map() | 빈 맵 생성 |
| map.set(key, value) | key에 value 저장 |
| map.get(key) | key에 해당하는 value 반환 (없으면 undefined) |
| map.has(key) | key가 존재하는지 여부 반환 |
| map.delete(key) | key-value 쌍 삭제 |
| map.clear() | 모든 요소 삭제 |
| map.size | 요소 개수 반환 |
let map = new Map();
map.set('a', 1);
map.set('b', 2);
map.set('b', 3); // 이미 존재하는 키를 또 set하려고 함
console.log(map.get('a')); // 1
console.log(map.has('b')); // true
console.log(map.get('b')); // 3
console.log(map.size); // 2 (변하지 않음)
Map 객체에서 키는 고유(unique) 해야 함.
map.set('b', 3)는 이미 존재하는 키 'b'의 값을 3으로 덮어씌우게 됨.
const map = new Map([
['a', 1],
['b', 2],
['c', 3]
]);
for (const [key, value] of map) {
console.log(key, value);
}
const map = new Map([
['a', [1, 2]],
['b', [3, 4]],
]);
for (const [key, value] of map) {
value.push(99); // 가능! map 내부의 배열도 변경됨
map.set(key, [...value, 999]); // 새로운 배열로 대체 (불변성 유지하고 싶을 때)
}
for (const [key, value] of map.entries()) {
console.log(key, value);
}
// 출력:
// a 1
// b 2
// c 3
const map = new Map([
['a', 1],
['b', 2],
['c', 3]
]);
for (const key of map.keys()) {
console.log(key);
}
// 출력:
// a
// b
// c
for (const value of map.values()) {
console.log(value);
}
// 출력:
// 1
// 2
// 3
if (`${value}` === 1) // flase : 문자열 '1' === 숫자 1
map.set(1, "number");
map.set("1", "string");
console.log(map.get(1)); // "number"
console.log(map.get("1")); // "string"
map[0] // 사용 불가
map.get(key)을 사용해야 함const arr = [1, 1, 2, 3, 2, 4];
const map = new Map();
for (const num of arr) {
map.set(num, (map.get(num) || 0) + 1);
}
console.log(map); // Map { 1 => 2, 2 => 2, 3 => 1, 4 => 1 }
const answer = [];
for (const [key, value] of map) {
if (value === 1) {
answer.push(key);
}
}
value기준(숫자)으로 오름차순
let map = new Map([
['a', thisTurn[0]],
['b', thisTurn[1]],
['c', thisTurn[2]]
]);
// 1. Map을 배열로 변환
let sortedEntries = [...map.entries()].sort((a, b) => a[1] - b[1]);
// 2. 다시 Map으로 변환
let sortedMap = new Map(sortedEntries);
// 출력 확인
for (const [key, value] of sortedMap) {
console.log(key + "=" + value);
}
map.entries()는 [key, value] 형태의 배열 iterator를 반환
sort((a, b) => a[1] - b[1]): value 기준으로 정렬 (a[1], b[1]이 value)
다시 new Map(...)으로 감싸면 정렬된 Map 객체 생성됨
key기준(문자)으로 오름차순
기본
let map = new Map([
['b', 20],
['a', 10],
['c', 30]
]);
// 1. entries 배열로 변환 후 key 기준 정렬
let sortedEntries = [...map.entries()].sort((a, b) => {
if (a[0] < b[0]) return -1;
if (a[0] > b[0]) return 1;
return 0;
});
// 2. 다시 Map으로 만들기
let sortedMap = new Map(sortedEntries);
// 확인 출력
for (const [key, value] of sortedMap) {
console.log(key + "=" + value);
}
localCompare 사용하여 정렬
let sortedMap = new Map([...map.entries()].sort((a, b) => a[0].localeCompare(b[0])));
localeCompare는 문자열 비교 함수라서 알파벳 순서대로 정확하게 정렬됨
숫자 키라면 a[0] - b[0] 써도 됨
let map = new Map();
map.set("numbers", [1, 2, 3]);
let key = "numbers";
if (map.has(key)) {
let numbersArray = map.get(key);
console.log("숫자 목록:", numbersArray); // 숫자 목록: [ 1, 2, 3 ]
}
let arrMap = new Map([
[a, [Math.abs(card - aLast), aLast]],
[b, [Math.abs(card - bLast), bLast]],
[c, [Math.abs(card - cLast), cLast]],
[d, [Math.abs(card - dLast), dLast]]
]);
이걸 Math.abs(card - aLast) 값 기준으로 정렬하고싶으면?
let sortedArrMap = new Map(
[...arrMap.entries()].sort((a, b) => a[1][0] - b[1][0])
);
let sortedMap = new Map([...map.entries()].sort((a, b) => a[0].localeCompare(b[0])));
localeCompare는 문자열 비교 함수라서 알파벳 순서대로 정확하게 정렬됨let arrMap = new Map([
[a, [Math.abs(card - aLast), aLast]],
[b, [Math.abs(card - bLast), bLast]],
[c, [Math.abs(card - cLast), cLast]],
[d, [Math.abs(card - dLast), dLast]]
]);
for (const [key, [diff, last]] of m) {
console.log(`${key}: 차이=${diff}, 마지막값=${last}`);
}
let arrMap = new Map([
[a, [Math.abs(card - aLast), aLast]],
[b, [Math.abs(card - bLast), bLast]],
[c, [Math.abs(card - cLast), cLast]],
[d, [Math.abs(card - dLast), dLast]]
]);
위의 구조는 아래와 같음
Map {
a => [diffA, aLast],
b => [diffB, bLast],
c => [diffC, cLast],
d => [diffD, dLast]
}
❓ 만약 cLast에 접근하려면?
arrMap.get(c)[1]
arrMap.get(c) : [Math.abs(card - cLast), cLast]1번 인덱스 → cLastlet sortedArrMap = new Map([
[a, [Math.abs(card - aLast), aLast]],
[b, [Math.abs(card - bLast), bLast]],
[c, [Math.abs(card - cLast), cLast]],
[d, [Math.abs(card - dLast), dLast]]
]);
const firstEntry = [...sortedArrMap.entries()][0]; // [key, [diff, last]]
const secondOfFirstValue = firstEntry[1][1]; // aLast
const firstValue = [...sortedArrMap.values()][0]; // [diff, last]
const secondOfFirstValue = firstValue[1]; // aLast
| 첫 번째 value | [...sortedArrMap.values()][0] |
그 value의 두 번째 값 (value[1]) | [...sortedArrMap.values()][0][1] |
| 또는 entries 기준으로 접근 | [...sortedArrMap.entries()][0][1][1] |
let selectedArr = [...sortedArrMap.keys()][0];
let arrMap = new Map([
[a, [Math.abs(card - aLast), aLast]],
...
]);
a.push(card);
for (const [key, [_, last]] of arrMap) {
key.push(777);
}
let selectedKey;
if (firstIndexValue[0] != secondIndexValue[0]){
selectedKey = [...sortedArrMap.keys()][0]; // 첫 번째 key. 즉, 배열 a~d 중 하나
if (card < firstIndexValue[1]){
selectedKey.push(card); //그 키를 수정해도 반영이 됨!!! 실제 배열 a~d 중 하나가 여기서 변경됨!!!
let a = [10];
let b = [20];
let arrMap = new Map([
[a, ['A']],
[b, ['B']]
]);
let selectedKey = [...arrMap.keys()][0];
selectedKey.push(99);
console.log(a); // [10, 99] : a 자체가 바뀜!!!
let result = new Map([
["A", 0],
["B", 0],
["C", 0]
]);
result.get("A"); // 0
let result = new Map([
["A", 0],
["B", 0],
["C", 0]
]);
let penalty = 5;
for (const key of result.keys()) {
result.set(key, result.get(key) + penalty);
}
console.log([...result.entries()]);
// [ [ 'A', 5 ], [ 'B', 5 ], [ 'C', 5 ] ]