자바스크립트에서는 객체와 배열을 이용해 다양한 프로그래밍을 할 수 있지만,
그럼에도 불구하고 현실세계의 문제를 프로그래밍적으로 반영하기에 부족한 부분이 있었고, 그것을 극복하고자
Map과 Set이라는 자료구조가 등장했다.
Map, Set의 목적
데이터의 구성, 검색, 사용을 기존 객체(Object) / 배열(Array)보다 효율적으로 처리하고자 한다.
#1. Map
Map의 특징
1. Key - Value pair (객체와 유사하다.)
2. Key에 어떠한 데이터 타입도 들어올 수 있다.
3. 검색, 삭제, 제거, 여부확인이 가능하다.
// 새로운 map 생성
const myMap = new Map();
// 아래 두개는 세트
myMap.set(‘key’, ‘value’); // 만든 map 내에 요소를 추가하기 위한 set 메서드
myMap.get(‘key’); // map 내 요소를 활용하기 위한 get 메서드
myMap.set(‘one’, 1);
myMap.set(‘two’, 2);
myMap.set(‘three',3);
console.log(myMap);
// Map(3) { 'one' => 1, 'two' => 2, 'three ' => 3 }
console.log(myMap.get('two')) // 2
생성자 함수(new Map) 을 사용해 map을 만들고, set 메서드를 활용하여 요소들을 추가하였다. (key - value pair)
해당 맵을 콘솔에 출력해보면 위 예제와 같이 iterator(반복자)를 반환한다.
Iterator(반복자)?
요소 하나하나를 반복할 수 있도록 배열 또는 객체와 비슷한 형태로 열거되어있는 자료구조
자세한 내용은 모던 자바스크립트 Deep Dive의 이터레이터 내용을 참고하면 좋을듯 하다.
앞서 말한 바와 같이 Map은 반복이 가능하기 때문에 for...of 반복문 사용이 가능하여 다양한 활용을 할 수 있다.
// keys 메서드를 활용해 키값들 활용
console.log(myMap.keys()); // {one, two, three}
// 반복문을 통해 key 반복
for(const key of myMap.keys()) {
console.log(key);
};
//one
//two
//three
// values 메서드를 활용해 벨류값들 활용
console.log(myMap.values()); {1,2,3}
for(const value of myMap.values()) {
console.log(value);
};
//1
//2
//3
// entries 메서드를 활용해 키-벨류값 활용
console.log(myMap.entries()); // {[one,1], [two,2], [three,3]};
for(const entry of myMap.entries()) {
console.log(entry);
};
//[one,1]
//[two,2]
//[three,3]
for ... of 반복문을 사용하여 각 요소들을 key, value, entry로 할당이 가능한 것이다.
이 외에도 size / has 메서드를 활용하여 길이와 특정한 키 값이 존재하는지 여부를 확인할 수 있다.
console.log(myMap.size) // map의 길이 3
console.log(myMap.has(“two”); // Key값을 기준으로 가지고 있는 요소 찾기 true/false => true
#3. Set
Set의 특징
1. 고유한 값을 저장하는 자료 구조
2. 값(value)만 저장한다.
3. 값이 중복되지 않는 유일한 요소로만 구성된다. (집합과 같은 특징)
4. 값 추가, 검색, 삭제, 제거, 존재여부 확인이 가능하다.
const mySet = new Set();
// 요소 추가 시 add 메서드를 활용한다.
mySet.add('value'); // value만 넣음
mySet.add('value2')
mySet.add('value2') // 같은 value를 넣어도
console.log(mySet); // Set(2) { 'value', 'value2' } value2 는 하나만 출력된다.
console.log(mySet.size); // 2
map과 마찬가지로 set도 반복이 가능한 이터레이터를 반환하기 때문에 for...of 반복문 사용이 가능하다.
for (const value of mySet.values()){ // value 값만 가지고 있기 때문에 values 메서드를 사용
console.log (value)
};
// value
// value2
중복된 값을 가지지 않는 set의 특성을 이용하여 교집합, 차집합을 구현해 볼 수 있는데 관련 내용은 MDN 문서를 확인해보자.
// 교집합
const intersection = new Set([...set1].filter(x => set2.has(x)));
// x값이 있는 요소들로 이루어진 set 반환
// 차집합
const intersection = new Set([...set1].filter(x => !set2.has(x)));
// x값이 없는 요소들로 이루어진 set 반환
Set을 활용한 예제 문제를 풀어보자 !
// 아래 결과와 같이 출력되도록 함수를 완성해 보세요.
// 자료구조 Set 의 인자로 배열을 넣으면 중복요소가 없는 배열을 반환받을 수 있습니다.
// spread syntax 를 사용해 보세요. Set을 배열로 변환할 수 있습니다.
function getNoDuplicates(arr) {
// 여기에 코드를 작성하세요.
}
const result = getNoDuplicates([1, 5, 2, 3, 4, 1, 2, 5, 6, 3]);
console.log(result); // 출력 결과: [1, 5, 2, 3, 4, 6]
정답 !
function getNoDuplicates(arr) {
const result = [...new Set(arr)]; // 배열 형태로 묶고 전개구문을 사용하였다.
return result
};
const result = getNoDuplicates([1, 5, 2, 3, 4, 1, 2, 5, 6, 3]);
console.log(result); // 출력 결과: [1, 5, 2, 3, 4, 6]
두 번째 줄에서 const result = new Set(arr); 로만 적게 될 경우 앞선 예제에서 봤듯이 Set 이터레이터 객체를 반환한다.
우리가 필요한 것은 배열의 형태이므로
result에 할당할 값들을 []로 배열형태로 묶어준 후 전개구문(Spread)로 요소들을 재할당 하였다.
Map 과 Set 의 경우도 최근에 나온 문법이고 활용이 많이 된다고 들었는데
이번 포스팅으로 조금이나마 정리가 되었으면 좋겠다.
정리할 수록 느끼는 것이긴 하지만.. 정말 많은 문법들이 존재하는 듯 하다.
오늘도 끝판왕에 반발짝 다가섰다.