일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 앱
- 안드로이드
- 테스트
- TEST
- Button
- Flutter
- CustomScrollView
- activity
- livedata
- DART
- scroll
- viewmodel
- tabbar
- Compose
- textfield
- android
- Coroutines
- binding
- Kotlin
- LifeCycle
- Navigation
- appbar
- drift
- 앱바
- 계측
- ScrollView
- data
- Dialog
- intent
- textview
- Today
- Total
Study Record
[JavaScript] 값의 집합 처리/조작하기 - Map, Set 본문
연상 배열 조작하기 - Map
Map 객체는 키/값 세트 이른바 연상 배열(해시)을 관리하기 위한 객체이다. 원래는 객체 리터럴로 연상 배열을 관리하는 것이 기본이었지만 ES2015에서 전용의 객체가 제공되었다.
Map 객체 기본 사용 방법
let m = new Map();
// set(key, value) : 요소 추가하기
m.set('One', "AAA");
m.set('Two', 'BBB');
m.set('Three', 'CCC');
m.set('Four', 'DDD');
// 요소의 수
console.log(m.size); // 4
// get(key) : key 에 상응하는 요소의 값 불러오기
console.log(m.get('Three')); // CCC
// has(key) : 지정한 key가 존재하는지 판정한다.
console.log(m.has('Six')); // false
// 키를 순서대로 취득
for(let key of m.keys()) {
console.log(key); // One Two Three Four
}
// 값을 순서대로 취득
for(let value of m.values()) {
console.log(value); // AAA BBB CCC DDD
}
// 키와 값을 순서대로 취득 (m 대신 m.enties() 도 가능)
for(let [key, value] of m) {
console.log(`${key} : ${value}`); // One : AAA , Two : BBB , Three : CCC , Four : DDD
}
// delete(key) : 지정한 키의 요소 삭제
m.delete("Three");
console.log(m); // Map(3) { 'One' => 'AAA', 'Two' => 'BBB', 'Four' => 'DDD' }
// 모든 요소 삭제하기
m.clear();
console.log(m.size); // 0
Map 객체 생성 예시)
let m1 = new Map([[1, 'T'], [2, 'G'], [3, 'F'], [4, 'A']]);
let m2 = new Map();
m2.set(1, 'T');
m2.set(2, 'G');
m2.set(3, 'F');
m2.set(4, 'A');
// 동일하다. Map(4) { 1 => 'T', 2 => 'G', 3 => 'F', 4 => 'A' }
console.log(m1);
console.log(m2);
객체 리터럴과 Map 객체의 차이
㉮ Map 객체는 임의의 형으로 키를 설정할 수 있다.
객체 리터럴에서는 프로퍼티명을 키로 대체하고 있으니 키로 이용할 수 있는 것은 문자열뿐이다. Map 객체는 임의의 형을 키로 설정할 수 있다. Nan 도 가능하다.
㉯ Map의 사이즈를 취득할 수 있다.
객체 리터럴에서는 키/값의 개수를 취득할 수 없다. 따라서 for/in 루프 등으로 객체를 수동으로 카운트해야하지만 Map 에서는 size 프로퍼티를 사용하여 등록된 키/값의 사이즈를 취득할 수 있다.
㉰ 클린 맵 을 만들 수 있다.
객체 리터럴에서는 그 실체가 Object 객체이다. 따라서 Object 객체가 표준으로 준비하고 있는 프로퍼티(키)가 처음부터 존재한다. 빈 객체 리터럴을 작성한 시점임에도 이미 비어 있지 않은 상태인 것이다.
그러나 Map 객체는 전용의 객체이므로 완전히 빈 연상 배열을 생성할 수 있다. Object 객체에서도 create 메서드로 강제적으로 빈 객체를 생성할 수 있지만 클린 맵을 생성하고자 한다면 Map 객체를 이용하는 편이 좋다.
키에 관한 주의점
㉮ 특별한 NaN 이 특별하지 않다.
NaN 은 자기 자신과도 동등하지 않는 특별한 값이다.(NaN !== NaN) 그렇지만 Map 에서는 NaN === NaN 으로 간주한다.
var m = new Map([[NaN, 'hoge']]);
console.log(m.get(NaN)); // hoge
㉯ 키값이 객체 리터럴일 경우
var m = new Map([[{}, 'hoge']]);
console.log(m.get({})); // undefined
undefined 값이 나오는 이유는 객체와 같은 참조형을 비교하는 경우 참조의 비교가 된다. 즉, 객체를 참조하고 있는 메모리의 주소값을 서로 비교하게 된다. 따라서 동일하게 빈 객체 리터럴({})을 비교하는 것처럼 보여도 서로 다른 메모리의 주소값을 가르키므로 동일하지 않다.
올바른 예시)
var key = {};
var m = new Map([[key, 'hoge']]);
console.log(m.get(key)); // hoge
중복되지 않는 값의 집합 조직하기 - Set 객체
Set 객체는 중복되지 않은 값의 집합을 관리하기 위한 객체이다. Set 객체는 ES2015 부터 새롭게 도입된 객체이다. 키값이 따로 존재하지 않으며 값만 존재한다.
Set 기본 동작
let s = new Set();
// 값 추가하기
s.add(10);
s.add(20);
s.add(5);
// 동일한 값은 무시한다.
s.add(10);
// 지정한 값의 유무 판정하기
console.log(s.has(20)); // true
// 요소의 수
console.log(s.size); // 3
// 값을 순서대로 취득
for(let value of s.values()) {
console.log(value); // 10 20 5
}
for(let val of s) {
console.log(val); // 10 20 5
}
s.forEach(function(value, index, s) {
console.log(value); // 10 20 5
});
// 지정한 값 삭제하기
s.delete(5);
console.log(s); // Set(2) {10, 20}
// 지정한 요소 모두 삭제하기
s.clear();
console.log(s.size); // 0
NaN 객체의 비교
NaN 은 아무리 추가해도 서로 동일한 값으로 간주한다. 하지만 객체 리터럴은 참조형으로 차지하고 있는 메모리 값의 정보를 갖고 있는 참조형이므로 서로 다른 요소로 간주한다.
let s = new Set();
s.add(NaN);
s.add(NaN);
console.log(s.size); // 1
let s2 = new Set();
s2.add({});
s2.add({});
s2.add({});
console.log(s2.size); // 3
'웹 > Javascript' 카테고리의 다른 글
[JavaScript] 정규 표현으로 문자 조작하기 - RegExp 객체 (0) | 2025.03.13 |
---|---|
[JavaScript] 날짜와 시간 데이터 조작하기 - Date 객체 (1) | 2025.03.13 |
[JavaScript] 값의 집합 처리/조작하기 - Array (1) | 2025.03.11 |
[JavaScript] 심볼 작성하기 (Symbol 객체) (1) | 2025.03.11 |
[JavaScript] 기본 데이터 취급을 위한 객체(string, number, math) (1) | 2025.03.11 |