개발일지/JavaScript ES6

[18~20] Map, Set / Model, Collection 클래스 / Product, Products /

꾸주니=^= 2024. 12. 2. 15:38

Map

Map은 ES6에서 추가된 새로운 데이터 구조로, 키-값 쌍을 저장하는 용도로 사용된다. Map 객체는 일반적인 자바스크립트 객체와 비슷하지만 몇 가지 중요한 차이점이 있다.

  • 키의 타입: Map의 키는 객체를 포함한 모든 값이 될 수 있다. 반면 일반 객체의 키는 반드시 문자열이나 심볼이어야 한다.
  • 저장 순서 유지: Map은 키-값 쌍이 삽입된 순서를 유지한다.

 

코드 설명

1. new Map()으로 빈 Map 객체를 생성
2. m.set('a', 1)와 같이 .set() 메서드를 통해 'a', 'b', 'c'라는 키에 각각 1, 2, 3을 설정
3. _.go 함수형 파이프라인을 구현하기 위해 자주 사용되는 형태로, 여러 개의 함수를 순차적으로 실행하는 방식이다.
4. 첫 번째 인자 m (Map 객체)을 넘겨준다. 즉, 이 Map이 파이프라인의 첫 번째 입력 값이다.
5. _.filter(([k, v]) => v % 2): 이 부분은 Map 객체의 각 키-값 쌍 ([k, v])에 대해 필터링하는 함수.
   여기서 v % 2가 참인 경우(즉, 값이 홀수인 경우)만 남긴다.
6. entries => new Map(entries): 필터링된 결과를 다시 새로운 Map 객체로 변환. entries는 필터링된 키-값 쌍 목록

실행 결과

{ 'a' => 1, 'c' => 3 }

 

Set

Set은 ES6에서 추가된 데이터 구조로, 중복되지 않는 값들의 집합을 저장하기 위해 사용된다.
Set은 다음과 같은 특징을 가진다:

  • 중복 불허: Set에 저장된 값은 중복이 불가능하다. 따라서 동일한 값을 여러 번 추가해도 하나의 값만 저장된다.
  • 순서 유지: 삽입된 순서대로 값을 기억하나, Set 내부의 값에는 인덱스가 없다.

 

코드 설명

1. new Set()으로 빈 Set 객체를 생성한다.
2. add() 메서드를 통해 각각 10, 20, 30을 Set에 추가한다. 이 값들은 중복되지 않기 때문에 모두 Set에 포함된다.
3. _.reduce(add, s): 이 부분은 Set 객체 s에 있는 값을 모두 합산하는 작업을 수행한다.

 

실행 결과

60

 

map과 set  특징 비교

특성 Map Set
저장 형태 키-값 쌍 (key-value pairs) 단일 값 (value)
키의 타입 모든 자료형 가능 (객체 포함) 값만 저장, 키는 사용하지 않음
중복 허용 여부 키는 중복 불가, 값은 중복 가능 모든 값 중복 불가
순서 유지 삽입된 순서 유지 (Map 내부 순서) 삽입된 순서 유지 (Set 내부 순서)
데이터 접근 get(key) 메서드로 접근 존재 여부를 확인하거나(has(value)) 전체 순회 (forEach)

 


Model, Collection 클래스

Collection 클래스가 정의되어 있고, 이 클래스는 모델 객체들을 관리하는 역할을 한다.

  1. 생성자 (constructor):
    • constructor(models = [])는 Collection을 초기화하는 함수이다.
    • 기본 값으로 빈 배열을 받아서, 이 배열을 내부 변수 this._models에 저장한다.
  2. at(idx) 메서드:
    • 인덱스 (idx)로 특정 모델을 가져올 수 있다.
    • this._models[idx]를 반환하여 지정된 위치의 모델을 반환한다.
  3. add(model) 메서드:
    • 모델 객체 Collection에 추가하는 메서드이다.
    • this._models.push(model)을 통해 models 배열에 새로운 모델을 추가한다.
    • 추가 후에는 현재 객체 (this)를 반환하여 메서드 체이닝이 가능하다.
  4. [Symbol.iterator]():
    • Symbol.iterator 메서드는 이터레이터를 정의한다.
    • yield* this._models를 사용하여 this._models 배열의 모든 항목을 순회할 수 있도록 한다.
    • 이를 통해 Collection 객체를 for...of 과 같은 구문에서 사용할 수 있다.

 

코드의 하단 부분에서 Collection을 사용하고 있다.

  • new Collection(): 새로운 Collection 객체를 생성한다.
  • add() 메서드를 통해 Model 객체들을 Collection에 추가한다. 여기서 Model 객체는 { id: 1, name: 'AA' }와 같은 데이터를 가진다.
  • console.log(coll.at(2).get('name')): 인덱스 2에 있는 모델의 name 속성 값을 출력한다. 이 경우 'CC'가 출력된다.

 

다음은 Lodash와 비슷한 형태로 보이는 라이브러리를 사용하여 Collection 객체를 다루는 예제이다.

  1. L.map(m => m.get('name')):
    • coll 내의 각 모델에 대해 name 속성을 가져와 새로운 배열로 만든다.
    • 즉, 각 모델의 이름을 추출하는 작업이다.
  2. _.each(console.log):
    • 각 이름을 console.log로 출력하는 작업이다.
  3. _.each(m => m.set('name', m.get('name').toLowerCase())):
    • Collection 내부의 각 모델에 대해 name 속성을 소문자로 변경한다.
    • m.set('name', m.get('name').toLowerCase())을 통해 변경된 값을 모델에 설정한다.

 

이와 같이 Collection Model은 데이터를 구조화하고, 이를 다양한 방식으로 관리하고 처리하기 위해 사용된다.

 


Product, Products - 메서드를 함수형으로 구현하기

Product Products는 서로 연관된 데이터 모델을 정의하고 관리하는 클래스이다.

1. Product 클래스

  • Product 클래스는 Model을 상속하고 있습니다.
  • Product는 개별 제품을 나타내는 단순한 데이터 모델입니다. 여기에서는 별도의 메서드를 정의하지 않고, Model의 기능을 그대로 사용합니다.

2. Products 클래스

  • Products 클래스는 여러 개의 Product 객체를 관리하는 Collection을 상속받습니다.
  • 주요 메서드는 다음과 같습니다:
    • getPrices(): 모든 Product 객체의 가격만을 추출하여 반환합니다. 여기서는 L.map()을 사용하여 가격을 추출합니다.
    • totalPrice(): 모든 Product 객체의 가격을 합산하여 반환합니다. addAll()을 사용해 모든 가격을 누적합합니다.

 

실행 결과