자바스크립트 코딩의 기술_Collection으로 데이터 관리하기_2
자바스크립트 2021. 5. 23. 16:40(본 포스팅은 길벗의 '자바스크립트-코딩의 기술' 책을 공부하면서 작성되었습니다_내돈내산)
2021.05.23 - [자바스크립트] - 자바스크립트 코딩의 기술_Collection으로 데이터 관리하기_1
4. 맵으로 명확하게 키-값 데이터를 갱신하라
- 일반적으로 '키-값 쌍이 자주 추가되거나 삭제되는 경우', '키가 문자열이 아닌경우' 대표적인 두가지 상황에서 객체보다 맵(Map)을 선택하는 것이 더 나은 결과를 가져옴.
- 객체와 Map 의 정보를 갱신하는데 있어 추가, 삭제, 모든조건제거 이 세가지의 방법이 필요하며, 서로 구현하는 방법도 달라지게 됨.
// 객체를 다룰 때
let filter = {}; // 객체 선언 및 할당
function addFilters(filters, key, value) {
filters[key] = value; // 조건추가
}
function deleteFilters(filters, key) {
delete filters[key]; // 조건 삭제
}
function clearFilters(filters) {
filters = {}; // 객체 초기화
return filters;
}
// Map 을 다룰때
let filters = new Map();
const petFilters = new Map();
function addFilters(filters, key, value) {
filters.set(key, value); // 조건추가
}
function deleteFilters(filters, key) {
filters.delete(key); // 조건 삭제
}
function clearFilters(filters) {
filters.clear(); // 객체 초기화
}
- 위의 코드에서 볼 수 있듯이 객체의 경우 단순히 중괄호만으로 선언이 가능하며, Map의 경우 생성자를 이용해 생성시켜주어야 한다. 그리고 Map 의 메서드를 이용해 조작이 가능해지게 된다(set(key, value)를 이용해 원소의 갱신 또는 추가가 가능해짐).
- 또한 Map의 경우 키값이 제한되지 않는다. 객체의 경우 키값이 문자로만 제한되지만 Map 의 경우 정수타입의 데이터도 키값으로 활용이 가능하다. (객체는 정수를 사용한 경우 전부 문자열로 치환되어 저장되어짐.
// Map 의 주요한 메서드
let filters = new Map() // 맵 선언
filters.set('key', 'value') // 맵에 데이터 추가
filters.get('key') // 'key'에 해당하는 value 반환
filters.delete('key') // 'key'에 해당하는 key-value 쌍 삭제
filters.clear() // 맵컬렉션 초기화(새로운 인스턴스 생성 필요 없음)
5. 맵과 펼침 연산자로 키-값 데이터를 순회하라.
- 키-값 컬렉션에 항목을 자주 추가하거나 삭제하는 경우는 객체보다 맵을 사용하는 것이 적합하다.
- 객체는 순회하기가 매우 번거롭고, 순회하기 위해서는 변환하는 작업이 필요하다. for... in문을 사용할 수 있지만, 객체 키 외에는 접근방법이 없음.
- 맵은 직접 순회가 가능하다.
// 객체 순환 방법
const filters = {
color: 'black',
breed: 'labrador',
};
function getAppliedFilters(filters) {
const keys = Object.keys(filters);
const applied = [];
for (const key of keys) {
applied.push(`${key}:${filters[key]}`);
}
return `Your filters are: ${applied.join(', ')}.`;
}
// Yout filters are color:black, breed:labrador
- Object.keys( )를 이용해서 객체의 일부를 배열로 옮긴다.
- for문으로 키를 순회한다.
- for문을 실행하는 동안 객체를 참조해 값을 꺼낸다.
- 필터링 조건을 정렬하기 위해서는 먼저 키를 정렬해야 함(객체에서 순서가 보장되지 못함)
// 맵 이터레이터 사용
const filters = new Map()
.set('color', 'black')
.set('breed', 'labrador');
function checkFilters(filters) {
for (const entry of filters) {
console.log(entry);
}
}
// ['color', 'black']
// ['breed', 'labrador'
// entries( ) 메서드
filters.entries( );
// MapIterator{ ['색상', '검정색'], ['견종', '레브라도리트리버'] }
function getAppliedFilters(filters) {
const applied = [];
for (const [key, value] of filters) {
applied.push(`${key}:${value}`);
}
return `Your filters are: ${applied.join(', ')}.`;
}
// 'Your filters are: color:black, breed:labrador.'
- 몇가지 값을 동시에 넘겨줌.
- 이터레이터는 키-값 쌍을 넘겨줌.
- 위와같은 코드를 entries( )라는 메서드를 이용해 맵 이터레이터를 반환하게 할 수 있음.
- 결과적으로 훨씬 단순하면서도 원래의 데이터 구조를 유지하는 코드를 작성할 수 있음.
- 맨 아래에 있는 getAppliedFilters함수를 보았을때, Map 객체 자체는 iterator로 키-값쌍을 배열로 반환하기 때문에 가능한 코드 작성법이다.
- 맵에서도 펼침연산자를 사용함에 따라 정렬문제를 해결할 수 있다. 맵자체가 순서를 저장하기는 하지만 배열처럼 정렬메서드가 내장되어있지않게 됨. filter.sort( )와같은 방법으로 정렬이 불가능하다.
[...filter];
// [['color', 'black'], ['breed', 'labrador']]
function sortByKey(a, b) {
return a[0] > b[0] ? 1 : -1;
}
function getSortedAppliedFilters(filters) {
const applied = [];
for (const [key, value] of [...filters].sort(sortByKey)) {
applied.push(`${key}:${value}`);
}
return `Your filters are: ${applied.join(', ')}.`;
}
// 'Your filters are: breed:labrador, color:black.'
// 맵객체에 펼침연산자를 사용하여 sort( ) 함수를 적용시킨 사례
function getSortedAppliedFilters(filters) {
const applied = [...filters]
.sort(sortByKey)
.map(([key, value]) => {
return `${key}:${value}`;
})
.join(', ');
return `Your filters are: ${applied}.`;
}
// 'Your filters are: breed:labrador, color:black.'
- 이전에 생성한 맵객체를 배열안에 펼쳐넣는 순간 맵객체를 배열로 변환이 가능하며, 이를 통해 내부 배열에 정렬메서드를 적용시킬 수 있게 된다.
- 맵객체에 펼침연산자를 적용시켜 배열화 시킨 후 sort( ) 메서드를 적용시키면 배열을 순회하게 되고, 배열의 map( ) 메서드를 이용해 원하는 작업을 진행할 수 있음.
6. 맵 생성 시 부수 효과를 피하라.
- 맵의 인스턴스를 이용해 작업할때 맵의 사본생성, 부수효과 등을 피하면서 맵을 변경하는 것이 중요함.
- 두가지 맵 객체를 서로 합칠 때, 그러니까 기본 맵에 다른 맵객체를 덮어씌울때 맵의 사본을 만드는 작업을 통해 진행이 가능하다.
function applyDefaults(map, defaults) {
const copy = new Map([...map]);
for (const [key, value] of defaults) {
if (!copy.has(key)) {
copy.set(key, value);
}
}
return copy;
}
- 위의 코드처럼 펼친연산자를 이용해 배열안에 map 객체를 펼쳐놓음으로써 원하는 맵 객체의 사본을 생성시킬 수 있다. 필터링 조건의 사본을 생성하였고, 여기에 기본값을 적용했다. 이런식의 코딩을 함으로써 원본 기본값은 변경되지 않지만 사용자가 원하는 값을 가진 Map 객체를 생성하였다.
- 다른 방안으로는 맵이 하나의 키를 한번만 사용할 수 있는 성질을 이용한다. 즉, 새로운 키로 맵을 생성하면 어떤 값이든 해당 키에 마지막으로 선언한 값을 사용하게 됨.
- 위의 코드를 아래와같이 심플하게 고칠 수 있다(펼침연산자와 Map 의 기본성질을 사용)
function applyDefaults(map, defaults) {
return new Map([...defaults, ...map]);
}
7. 세트를 이용해 고윳값을 관리하라.
- 세트(Set)은 고유항목을 하나씩만 갖는 특화된 배열과 같다.
- 맵과 유사하지만, 세트의 새로운 인스턴스는 중첩하지 않은 배열을 인수로 받는다는데 있다.
// 기본적인 Set 객체 생성법
const color = ['검정색', '검정색', '갈색'];
const unique = new Set(colors); // Set {'검정색', '갈색'}
// 펼침연산자를 이용한 리팩토링
function getUnique(attributes) {
return [...new Set(attributes)];
}
- 위와같이 중복된 값을 제거하고 고유한 요소만 포함하는 Set 객체를 생성할 수 있으며, 변수에 할당하는 과정 없이 인스턴스를 생성하자 마자 펼침연산자를 이용이 가능하다.
- 세트의 경우 값을 추가할때는 add( ) 메서드를, 검증할 때는 has( ) 메서드를 사용한다. 또한, 세트에도 맵처럼 delete( )와 clear( ) 메서드가 있다.
- 세트에 항목을 추가할 때는 배열에 한번에 담아 전달할 수 잇지만, 반복문을 이용해 개별적으로 추가가 가능하다.
- 세트는 고유값을 가지는 컬렉션타입이기 때문에 세트에 없는 값은 추가할 수 있으며, 이미 세트에 존재하는 값을 추가할경우 자동적으로 무시된다.(이미 존재하는 값을 다시 넣더라도 원래값의 위치는 유지되어짐.)
'자바스크립트' 카테고리의 다른 글
자바스크립트 코딩의 기술_반복문 작성의 기술_1 (0) | 2021.05.30 |
---|---|
자바스크립트 코딩의 기술_조건문 깔끔하게 작성하기 (0) | 2021.05.29 |
자바스크립트 코딩의 기술_Collection으로 데이터 관리하기_1 (0) | 2021.05.23 |
자바스크립트 코딩의 기술_배열로 데이터 관리하기 (0) | 2021.05.22 |
자바스크립트 코딩의 기술_변수할당 (0) | 2021.05.22 |