Developer/자바스크립트

자바스크립트 , Map

단님 2024. 6. 4. 20:31
728x90

 

자바스크립트의 객체는 여러형태의 데이터를 손쉽게 묶을 수 있는 편리한 자료구조이다.

ECMA 6에서 추가된 맵의 자료구조형태가 추가되었는데,

ECMA6 에서 변수 var 에서 let 과 const가 추가된 배경과 비슷하다.

객체에서는 문자열 또는 심볼의 프로퍼티를 사용할 수 있었는데,

맵객체에서는 함수나 객체를 포함하고 , 숫자형태를 제외한 모든 형태의 프로퍼티가 가능하다.

맵은 키가 있는 데이터를 저장한다는 점에서 객체와 유사하지만 다양한 형태의 프로퍼티가 가능하다는 점이 차이가 크다.

 

객체처럼 . 이나 [] 로 접근할 필요 없이 메소드로만으로도 프로퍼티를 수정하거나 조회할 수 있다.

객체는 속성값이 얼마나 있는지 조회할 수 없으나 Map은 속성의 갯수를 파악할 수 있다(Map.size)

객체는 속성이 같을 떄 충돌이 일어날 수 있으나 , Map 은 key가 고유해야만 한다.

 

맵객체는 for...of 를 통해 깔끔하게 순회가 가능하다.

 

언제 Map 을 써야할까 ?

가장 큰 장점으로 프로퍼티에 대한 접근이 쉽다는것을 이용해

객체의 프로퍼티가 자주 변경될 때 맵을 이용하면 편리하게 접근이 가능하다.

 

Map 객체의 메서드 들
  • map.set(key, value) – key를 이용해 value를 저장한다.
  • map.get(key) – key에 해당하는 값을 반환한다. key가 존재하지 않으면 undefined를 반환한다.
  • map.has(key) – key가 존재하면 true, 존재하지 않으면 false를 반환한다.
  • map.delete(key) – key에 해당하는 값을 삭제한다.
  • map.clear() – 맵 안의 모든 요소를 제거한다.
  • map.size – 요소의 개수를 반환한다.
 
let myMap = new Map([['a',111],['b',222],['c',333]]);
새로운 Map 의 생성 + 초기화 동시작업.
 
console.log(`** Test1 => size=${myMap.size}, a=${myMap.get('a')}`);
    myMap.set('a','aaa'); //수정
    console.log(`** Test2 => size=${myMap.size}, a=${myMap.get('a')}`);
    myMap.set('d','ddd'); // 추가
    console.log(`** Test3 => size=${myMap.size}, d=${myMap.get('d')}`);
    myMap.delete('b');    // 삭제
    console.log(`** Test4 => size=${myMap.size}, b=${myMap.get('b')}`); //undefined
    // 존재 확인
    console.log(`** Test5 => 존재확인 a=${myMap.has('a')}, k=${myMap.has('k')}`) ;

 

 

    let sMap = new Map();
    sMap.set('1','오원희');
    sMap.set('2','어성은');
    sMap.set('3','이진기');
    sMap.set('4','유희상');

새로운 Map 의 생성 후 set 메서드를 통한 추가 , 초기화

 

for of 를 통한 순회작업.

    // 2) 활용 :  for ~ of
    // => 출력1
    for ( const [key, value] of sMap ) {
      console.log(`** for 1 =>  key=${key}, name=${value}`);
    } //for
    // => 출력2 : entries(맵의 기본 이터레이터) 적용됨
    for ( const ss of sMap ) {
      console.log(`** for 2 =>  ss=${ss}`);
      console.log(`** for 3 =>  ${ss[0]}번= ${ss[1]}`);
    } //for

const [key, value] of sMap -> key 와 value를 배열 형태의 모양으로 가져옴을 알 수 있다.

const ss of sMap 의 ss 란 key와 value 가 합쳐진 배열 형태를 이루고 있고,

내부적으로 접근할 때에 배열 index를 통하여 접근이 가능.

${ss[0]}번= ${ss[1]}  -> ss[0] : key , ss[1] : value

 

key 가 객체이거나 value 가 객체인 경우의 접근도 살펴보도록 하자.

1) key 가 객체인 경우.

    const u1 = {id:'banana1', name:'홍길동1'};
    const u2 = {id:'banana2', name:'홍길동2'};
    const u3 = {id:'banana3', name:'홍길동3'};
    const u4 = {id:'banana4', name:'홍길동4'};
    // => Map 생성
    const uMap = new Map();
    // => 초기화
    uMap.set(u1 , 'Gold');
    uMap.set(u2 , 'Silver');
    uMap.set(u3 , 'Diamond');
    uMap.set(u4 , '일반');

    // => 과제 : for ~ of 이용해서 
    // 1) id, name 출력하기
    for ( let u of uMap.keys() ){
    	console.log(`** User => id=${u.id}, name=${u.name}`);
	  } 
    // 2) id 와 등급(value) 출력
    for ( let u of uMap.entries() ){
    	console.log(`** User => ${u[0].id}= ${u[1]} 등급`);
	  }

 

객체라는 점에서 접근을 해야한다.

객체는 value 값을 얻기위해서는 객체주소.key 를 입력해야 value를 얻을 수 있다.

그점을 활용하여 접근한다.

for ( let u of uMap.keys() ) 의 uMap.key()란  uMap(key , value) 로 보았을때

key 가 객체이기 때문에 key에 대한 접근을 uMap.key() 를 통해 할 수 있다.

 

uMap 전체를 접근하기 위해서는 uMap.entries() 를 쓰기도 하고 , uMap 을 쓰기도 한다.

단 , 전체로 접근할때에는 [key, value] of sMap 이런식으로 구조분해 할당 하지 않았다면 ,

배열로서 접근하여 인덱스위치를 명시해주자.

 

 

2)객체가 value 인 경우

    // ** ** 활용2 : value 가 객체인 경우
    // => Student 프로토타입 을 작성 ( 속성: nick, name )
    function Student(nick, name) {
      this.nick = nick;
      this.name = name;
    }
    // => 인스턴스를 4개 만들고 생성자 함수를 활용하여
    // const m1 = new Student('용감한 수달', '오원희');
    const m2 = new Student('춤추는 상괭이', '어성은');
    const m3 = new Student('귀여운 바다사자', '이진기');
    const m4 = new Student('지혜로운 북극곰', '유희상');
   
    // => Map 에 담기 (key: 1~4, value: Student) 
    let mMap = new Map(); 
    // Map에 넣기 (key는 번호 eg.1~4, value 는 student)
    mMap.set('1', new Student('용감한 수달', '오원희'));
    mMap.set('2', m2);
    mMap.set('3', m3);
    mMap.set('4', m4);
    // => 출력1
    for (const [key, value] of mMap) {
      console.log(`** Member => Key=${key}, ${value.nick}, ${value.name}`);
    }
    // => 출력2
    for (let mm of mMap.entries()) {
            console.log(`key=${mm[0]}, nick=${mm[1].nick}, name=${mm[1].name}`);
    }
    for (const mm of mMap) {
      console.log(`** Member => Key=${mm[0]}, ${mm[1].nick}, ${mm[1].name}`);
    }

접근 방식은 똑같다. 위의 글을 참조하여 이해해보자.