Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- Memoir
- JavaScript
- 백준 javascript
- 스프링 빈
- 스프링 컨테이너
- 리눅스마스터1급
- 연습문제
- 문자열
- 자바
- 리눅스
- 카카오
- 명령어
- 리눅스마스터 1급 정리
- toCharArray
- Linux
- 고잉버스
- 월간코드챌린지
- 개발자 회고록
- Kotlin
- 백준 java
- 코테
- 프로그래머스
- GoingBus
- map
- 자바스크립트 코딩의 기술
- 코딩테스트
- 리눅스마스터 3과목
- java 백준 1차원 배열
- Java
- 반복문
Archives
- Today
- Total
hoon's bLog
Javascript 자바스크립트 코딩의 기술 3장 특수한 컬렉션을 이용해 코드 명료성을 극대화하라 (2) 본문
반응형
3장 특수한 컬렉션을 이용해 코드 명료성을 극대화하라
tip14. 맵과 펼침 연산자로 키-값 데이터를 순회하라
객체는 순회하기가 번거롭다. 그나마 for ...in문을 사용할 수 있지만 키 외에는 접근할 수 없다.
const filters = {
color: 'black',
breed: 'Retriever'
};
function getAppliedFilters(filters) {
const keys = Object.keys(filters);
const applied = [];
for (const key of keys) {
applied.push(`${key}:${filters[key]}`);
}
return `선택한 조건은 ${applied.join(',')} 입니다.`;
}
- Object.keys()로 객체의 키를 배열로 옮기고, for문으로 키를 순회하면서, 객체를 참조해 값을 꺼낸다.
- 또한, 객체의 순서를 보장되지 않으므로 정렬을 할 수 없다. 필터링 조건을 정렬하려면 키를 정렬해야 한다.
const filters = new Map()
.set('color', 'black')
.set('breed', 'Retriever')
filters.entries();
// MapIterator { ['color', 'black'], ['breed', 'Retriever']}
function getAppliedMapFilters(filters) {
const applied = [];
for (const [key, value] of keys) {
applied.push(`${key}:${value}`);
}
return `선택한 조건은 ${applied.join(',')} 입니다.`;
}
console.log(...filters);
// ['color', 'black'], ['breed', 'Retriever']
- ES2017부터 공식적으로 명세에 Object의 내장 메소드 Object.entries()로 추가되었다고 한다!
Map에서도 스프레드 연산자를 사용할 수 있다. - 배열은 단일 값만 반환되지만 Map은 키-값 쌍이 반환된다.
- 반면에 Map은 정렬과 순회에 필요한 기능이 내장되어 있다. 아래 코드를 통해 알아보자!!
const filters = new Map().set('색상','검정색').set('견종','래브라도리트리버')
function checkFilters(filters) {
for (const entry of filters) {
console.log(entry);
}
}
checkFilters(filters)
//["색상", "검정색"]
//["견종", "래브라도리트리버"]
filters.entries();
// MapIterator {"색상" => "검정색", "견종" => "래브라도리트리버"}
- entries()는 키-값 쌍으로 묶은 Map Iterator를 반환한다.
- Map은 직접 순회 가능하므로 키를 먼저 꺼낼 필요 없고, 해체 할당 문법으로 즉시 변수로 할당 할 수 있다.
function getAppliedFilters(filters) {
const applied = [];
for ( const [key, value] of filters ) {
applied.push(`${key}:${value}`);
}
return `선택한 조건은 ${applied.join(', ')} 입니다.`;
}
getAppliedFilters(filters);
- Map이 순서를 저장해 항상 맵의 첫 번째 항목을 첫 번째로 받지만, 배열 메서드처럼 sort() 메서드가 없다. 따라서 정렬을 위해 아래와 같이 코드를 수정해준다.
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 `선택한 조건은 ${applied.join(', ')} 입니다.`;
}
getSortedAppliedFilters(filters);
// "선택한 조건은 견종:래브라도리트리버, 색상:검정색 입니다."
- 위 코드에 문제점은 Map으로 시작했지만 실제 for문이 실제로 순회하는 것은 맵이 아닌 새로운 배열이다.
- Map을 배열로 변환해 함수를 단순하게 만들었고, 배열로 변환함으로써 배열 메서드도 사용이 가능하다.
- 앞에서 맵 객체를 이용한 함수 대신 배열 메서드를 체이닝을 사용해 작성하면 다음과 같다.
function getAppliedFilters(filters) {
const applied = [...filters]
.sort(sortByKey)
.map(([key, value]) => {
return `${key}:${value}`;
})
.join(', ');
return `선택한 조건은 ${applied} 입니다.`;
}
// "선택한 조건은 견종:래브라도리트리버, 색상:검정색 입니다."
tip15. Map 생성 시 부수 효과를 피하라
- 맵의 인스턴스를 이용해 작업하면 몇가지 문제점이 있다.
- 맵의 복사본은 어떻게 생성할까? 부수 효과를 피하면서 맵을 변경하려면 어떻게 해야 할까?
- 우선 복사, 조작 문제를 혼합한 예제를 살펴보자.
- 앞에 살펴봤던 반려견 입양 사이트 예제 코드에서 사용자가 필터링 조건을 선택했는데, 아마 필터링의 기본값도 필요할 것이다.
- 즉, 사용자가 명시적으로 설정하지 않는 조건에 대해서는 기본값을 적용, 추가로 사용자가 적용하는 필터링 조건은 기본값을 덮어 쓴다.
const defaults = new Map()
.set('색상','갈색')
.set('견종','비글')
.set('지역','캔자스')
const filters = new Map()
.set('색상', '검정색')
- 위와 같이 기본값과 추가 필터링 조건을 합칠려면 어떻게 해야될까?
- 부수 효과를 신경쓰지 않으면 has메서드를 사용해 키를 체크해 설정한다.
function applyDefaults(map, defaults) {
for (const [key,value] of defaults) {
if (!map.has(key)) {
map.set(key, value); // 여기서 filters를 조작한다.
}
}
}
console.log(filters);
// Map(3) {"색상" => "검정색", "견종" => "비글", "지역" => "캔자스"}
- 기본값, 사용자 데이터를 병합하는 것이 목적이라면 성공!
- 필터링 조건 객체에 대한 사용을 위해서, 데이터에 필터링 조건 적용, 사용자가 선택한 조건을 알려주는 부분을 고려해야 한다.
- 위 코드와 같은 경우에는 사용자가 선택한 조건에 기본값도 모두 노출 된다.
- 해결 방법은 entries, 펼침연산자를 사용하여 사본을 만드는 것이다. 아래 코드로 살펴보자.
function applyDefaults(map, defaults) {
const copy = new Map([...map]);
for (const [key,value] of defaults) {
if (!copy.has(key)) {
copy.set(key, value); // 여기서 filters를 조작한다.
}
}
return copy;
}
- 여러가지 키의 존재 여부를 일일이 확인하고 있다.
- Map은 객체와 마찬가지로 하나의 키를 한 번만 사용할 수 있다.
- 따라서, 새로운 키로 맵을 생성하면 어떤 값이든 해당 키에 마지막으로 선언한 값을 사용한다. 즉, 값을 설정하는 대신 갱신한다.
const filters = new Map().set('color', 'black').set('color', 'brown')
filters.get('color'); // 'brown'
- 그리고 위의 applyDefaults 함수를 개선 하면 아래와 같다!
function applyDefaults(map, defaults) {
return new Map([...defaults, ...map]);
}
Reference
자바스크립트 코딩의 기술 요약 / 정리
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Set/entries
728x90
반응형
'IT > Javascript' 카테고리의 다른 글
Javascript 자바스크립트 코딩의 기술 4장 조건문을 깔끔하게 작성하라 (0) | 2024.01.18 |
---|---|
Javascript 자바스크립트 코딩의 기술 3장 특수한 컬렉션을 이용해 코드 명료성을 극대화하라 (3) (0) | 2024.01.17 |
Javascript 자바스크립트 코딩의 기술 3장 특수한 컬렉션을 이용해 코드 명료성을 극대화하라 (1) (0) | 2024.01.04 |
Javascript 자바스크립트 코딩의 기술 2장 배열로 데이터 컬렉션을 관리하라 (2) (0) | 2023.11.16 |
Javascript 자바스크립트 코딩의 기술 2장 배열로 데이터 컬렉션을 관리하라 (1) (0) | 2023.11.15 |