(9) Set 와 Map 데이터 구조

15567 단어
Set 집합 은 중복 요소 가 없 는 목록 입 니 다. 개발 자 들 은 배열 요 소 를 방문 하 는 것 처럼 모든 요 소 를 하나씩 방문 하지 않 습 니 다. 일반적인 방법 은 주어진 값 이 특정한 집합 에 존재 하 는 지 확인 하 는 것 입 니 다.맵 집합 에는 여러 개의 키 값 이 포함 되 어 있 습 니 다. 집합 에 있 는 모든 요 소 는 각각 접근 가능 한 건 명 과 이에 대응 하 는 값 을 저장 하고 있 습 니 다. 맵 집합 은 자주 캐 시 에서 자주 사용 되 는 데 이 터 를 저장 합 니 다.Set 과 Map 은 모두 Object. is () 를 통 해 배 중 을 실현 한다.
1、Set
1) Set 자 체 는 구조 함수 로 Set 데이터 구 조 를 생 성 한다.
2) 배열 과 유사 하지만 구성원 의 값 은 유일 하 며 중복 되 는 값 이 없다.
set 구조의 인 스 턴 스 는 다음 과 같은 속성 이 있 습 니 다.
  • Set. prototype. constructor: 구조 함수, 기본 값 은 Set 함수 입 니 다.
  • Set. prototype. size: Set 인 스 턴 스 의 구성원 총 수 를 되 돌려 줍 니 다.
  • const set = new Set([1, 2, 3, 4, 4]);
    console.log(Set.prototype.constructor)
    console.log(set.size)
    

    네 가지 조작 방법.
  • add (value): 어떤 값 을 추가 하고 Set 구조 자 체 를 되 돌려 줍 니 다.
  • delete (value): 어떤 값 을 삭제 하고 불 값 을 되 돌려 삭제 에 성 공 했 는 지 여 부 를 표시 합 니 다.
  • has (value): 이 값 이 set 의 구성원 인지 아 닌 지 를 나타 내 는 불 값 을 되 돌려 줍 니 다.
  • clear (): 모든 구성원 을 삭제 하고 반환 값 이 없습니다.
  • const set = new Set([1, 2, 3, 4, 4]);
    set.add(5);
    set.add(6).add(7);
    //      set.add(6).add(7);
    //            
    console.log(set);
    console.log(set.has(7));
    console.log(set.delete(3));
    console.log(set);
    console.log(set.clear());
    console.log(set);
    console.log(set.size)
    

    Set 의 옮 겨 다 니 기
    set 구조의 인 스 턴 스 는 네 가지 옮 겨 다 니 는 방법 이 있 습 니 다. 구성원 을 옮 겨 다 니 는 데 사용 할 수 있 습 니 다.
  • keys (): 키 이름 을 되 돌려 주 는 달력
  • values (): 키 값 을 되 돌려 주 는 달력
  • entries (): 키 값 이 맞 는 스 트 리밍 기 를 되 돌려 줍 니 다
  • foreach (): 리 셋 함 수 를 사용 하여 각 멤버 를 옮 겨 다 니 기
  • let set = new Set(['red', 'green', 'blue']);
    
    for (let item of set.keys()) {
      console.log(item);
    }
    // red
    // green
    // blue
    
    for (let item of set.values()) {
      console.log(item);
    }
    // red
    // green
    // blue
    
    for (let item of set.entries()) {
      console.log(item);
    }
    // ["red", "red"]
    // ["green", "green"]
    // ["blue", "blue"]
    
    let set = new Set(['red', 'green', 'blue']);
    
    for (let x of set) {
      console.log(x);
    }
    // red
    // green
    // blue
    
    set = new Set([1, 4, 9]);
    set.forEach((value, key) => console.log(key + ' : ' + value))
    // 1 : 1
    // 4 : 4
    // 9 : 9
    

    forEach
    //   forEach
    const items = ['item1', 'item2', 'item3'];
    const copy = [];
    
    items.forEach(function(item){
      copy.push(item)
    });
    
    //set forEach
    

    foreach 가 배열 에 있 는 소개 프레젠테이션 foreach 가 다 릅 니 다.
    Set 를 사용 하면 집합 (Union), 교 집합 (Intersect), 차 집합 (Difference) 을 쉽게 실현 할 수 있 습 니 다.
    let a = new Set([1, 2, 3]);
    let b = new Set([4, 3, 2]);
    
    //   
    let union = new Set([...a, ...b]);
    // Set {1, 2, 3, 4}
    
    //   
    let intersect = new Set([...a].filter(x => b.has(x)));
    // set {2, 3}
    
    //   
    let difference = new Set([...a].filter(x => !b.has(x)));
    // Set {1}
    

    옮 겨 다 니 면서 원래 의 Set 구 조 를 동시에 바 꾸 려 면 현재 직접적인 방법 은 없 지만 두 가지 변통 방법 이 있다.하 나 는 원 Set 구 조 를 이용 하여 새로운 구 조 를 매 핑 한 다음 에 원래 의 Set 구조 에 값 을 부여 하 는 것 이다.다른 하 나 는 Array. from 방법 을 이용 하 는 것 이다.
    //    
    let set = new Set([1, 2, 3]);
    set = new Set([...set].map(val => val * 2));
    // set   2, 4, 6
    
    //    
    let set = new Set([1, 2, 3]);
    set = new Set(Array.from(set, val => val * 2));
    // set   2, 4, 6
    

    2、WeakSet
    1) WeakSet 구조 가 Set 와 유사 하고 중복 되 지 않 는 값 의 집합
    2) WeakSet 의 멤버 는 대상 일 뿐 다른 유형의 값 일 수 없다.
    Weak Set 구 조 는 다음 과 같은 세 가지 방법 이 있 습 니 다.
  • WeakSet. prototype. add (value): WeakSet 인 스 턴 스 에 새 멤버 를 추가 합 니 다.
  • WeakSet. prototype. delete (value): WeakSet 인 스 턴 스 의 지정 한 구성원 을 삭제 합 니 다.
  • WeakSet. prototype. has (value): 하나의 불 값 을 되 돌려 줍 니 다. 어떤 값 이 WeakSet 인 스 턴 스 에 있 는 지 여 부 를 표시 합 니 다.

  • 1) WeakSet 은 size 속성 이 없어 서 멤버 들 을 옮 겨 다 닐 수 없습니다.
    2) Weak Set 을 옮 겨 다 닐 수 없 는 이 유 는 멤버 들 이 약 한 인용 이기 때문에 언제든지 사라 질 수 있 습 니 다. 옮 겨 다 니 는 메커니즘 은 멤버 들 의 존 재 를 보장 할 수 없습니다. 옮 겨 다 니 는 것 이 끝나 자마자 멤버 들 이 찾 지 못 할 수도 있 습 니 다.Weak Set 의 한 용 도 는 DOM 노드 를 저장 하 는 것 입 니 다. 이 노드 들 이 문서 에서 제거 할 때 메모리 누 출 을 걱정 하지 않 아 도 됩 니 다.
    const ws = new WeakSet();
    const obj = {};
    const foo = {};
    
    ws.add(window);
    ws.add(obj);
    
    ws.has(window); // true
    ws.has(foo);    // false
    
    ws.delete(window);
    ws.has(window);    // false
    

    3、Map
    ES6 는 맵 데이터 구 조 를 제공 합 니 다.이것 은 대상 과 유사 하고 키 값 이 맞 는 집합 이지 만 '키' 의 범 위 는 문자열 에 국한 되 지 않 으 며 각종 유형의 값 (대상 포함) 을 키 로 사용 할 수 있다.즉, Object 구 조 는 '문자열 - 값' 의 대응 을 제 공 했 고 Map 구 조 는 '값 - 값' 의 대응 을 제 공 했 으 며 더욱 완벽 한 Hash 구조 구현 이다."키 쌍" 의 데이터 구조 가 필요 하 다 면, 맵 은 Object 보다 더 적합 합 니 다.
    const m = new Map();
    const o = {p: 'Hello World'};
    
    m.set(o, 'content')
    
    //         
    m.get(o) // "content"
    m.get({p: 'Hello World'})
    
    m.has(o) // true
    m.delete(o) // true
    m.has(o) // false
    
    //            
    // const map2 = new Map({
    //  'name': '  ',
    //  'title': 'Author'
    // });
    

    실례 적 인 속성 과 조작 방법
    1) size 속성 size 속성 은 맵 구조의 구성원 총 수 를 되 돌려 줍 니 다.
    const map = new Map();
    map.set('foo', true);
    map.set('bar', false);
    
    map.size // 2
    

    2)set(key, value)
    const m = new Map();
    
    m.set('edition', 6)        //      
    m.set(262, 'standard')     //     
    m.set(undefined, 'nah')    //    undefined
    

    set 방법 은 현재 맵 대상 을 되 돌려 주기 때문에 체인 으로 쓸 수 있 습 니 다.
    let map = new Map()
      .set(1, 'a')
      .set(2, 'b')
      .set(3, 'c');
    

    3) get (key) get 방법 은 key 에 대응 하 는 키 값 을 읽 습 니 다. key 를 찾 지 못 하면 undefined 로 돌아 갑 니 다.
    const m = new Map();
    
    const hello = function() {console.log('hello');};
    m.set(hello, 'Hello ES6!') //     
    
    m.get(hello)  // Hello ES6!
    

    4) has (key) has 방법 은 현재 맵 대상 에 키 가 있 는 지 여 부 를 나타 내 는 불 값 을 되 돌려 줍 니 다.
    const m = new Map();
    
    m.set('edition', 6);
    m.set(262, 'standard');
    m.set(undefined, 'nah');
    
    m.has('edition')     // true
    m.has('years')       // false
    m.has(262)           // true
    m.has(undefined)     // true
    

    5) delete (key) delete 방법 으로 키 를 삭제 하고 트 루 로 돌아 갑 니 다.삭제 에 실패 하면 false 로 돌아 갑 니 다.
    const m = new Map();
    m.set(undefined, 'nah');
    m.has(undefined)     // true
    
    m.delete(undefined)
    m.has(undefined)       // false
    

    6) clear () clear 방법 은 모든 구성원 을 삭제 하고 값 을 되 돌려 주지 않 습 니 다.
    let map = new Map();
    map.set('foo', true);
    map.set('bar', false);
    
    map.size // 2
    map.clear()
    map.size // 0
    

    옮 겨 다 니 는 방법 Map 구조 원생 은 세 개의 옮 겨 다 니 는 생 성 함수 와 옮 겨 다 니 는 방법 을 제공 합 니 다.
    keys (): 키 이름 의 달력 을 되 돌려 줍 니 다.values (): 키 값 을 되 돌려 주 는 달력 입 니 다.entries (): 모든 구성원 의 달력 을 되 돌려 줍 니 다.foreach (): 맵 을 옮 겨 다 니 는 모든 멤버.특히 주의해 야 할 것 은 맵 의 옮 겨 다 니 는 순 서 는 삽입 순서 다.
    const map = new Map([
      ['F', 'no'],
      ['T',  'yes'],
    ]);
    
    for (let key of map.keys()) {
      console.log(key);
    }
    // "F"
    // "T"
    
    for (let value of map.values()) {
      console.log(value);
    }
    // "no"
    // "yes"
    
    for (let item of map.entries()) {
      console.log(item[0], item[1]);
    }
    // "F" "no"
    // "T" "yes"
    
    //   
    for (let [key, value] of map.entries()) {
      console.log(key, value);
    }
    // "F" "no"
    // "T" "yes"
    
    //      map.entries()
    for (let [key, value] of map) {
      console.log(key, value);
    }
    // "F" "no"
    // "T" "yes"
    

    다른 데이터 구조 와 의 상호 전환
    (1) 맵 을 배열 로 전환
    const myMap = new Map()
      .set(true, 7)
      .set({foo: 3}, ['abc']);
    [...myMap]
    // [ [ true, 7 ], [ { foo: 3 }, [ 'abc' ] ] ]
    

    (2) 배열 이 맵 으로 전환
    맵 구조 함수 에 배열 을 전송 하면 맵 으로 전환 할 수 있 습 니 다.
    new Map([
      [true, 7],
      [{foo: 3}, ['abc']]
    ])
    // Map {
    //   true => 7,
    //   Object {foo: 3} => ['abc']
    // }
    

    (3) 맵 대상 전환
    모든 맵 의 키 가 문자열 이 라면 대상 으로 손상 없 이 전환 할 수 있 습 니 다.
    function strMapToObj(strMap) {
      let obj = Object.create(null);
      for (let [k,v] of strMap) {
        obj[k] = v;
      }
      return obj;
    }
    
    const myMap = new Map()
      .set('yes', true)
      .set('no', false);
    strMapToObj(myMap)
    // { yes: true, no: false }
    

    문자열 이 아 닌 키 이름 이 있 으 면 이 키 이름 은 문자열 로 바 뀌 어 대상 의 키 이름 으로 바 뀝 니 다.
    (4) 대상 이 맵 으로 전환
    function objToStrMap(obj) {
      let strMap = new Map();
      for (let k of Object.keys(obj)) {
        strMap.set(k, obj[k]);
      }
      return strMap;
    }
    
    objToStrMap({yes: true, no: false})
    // Map {"yes" => true, "no" => false}
    

    (5) 맵 이 JSON 으로 전환
    맵 을 JSON 으로 전환 하려 면 두 가지 상황 을 구분 해 야 한다.맵 의 키 이름 이 모두 문자열 인 경우 대상 JSON 으로 전환 하 는 것 을 선택 할 수 있 습 니 다.
    function strMapToJson(strMap) {
      return JSON.stringify(strMapToObj(strMap));
    }
    
    let myMap = new Map().set('yes', true).set('no', false);
    strMapToJson(myMap)
    // '{"yes":true,"no":false}'
    

    또 다른 경 우 는 맵 의 키 이름 에 비 문자열 이 있 습 니 다. 이 때 배열 JSON 으로 전환 하 는 것 을 선택 할 수 있 습 니 다.
    function mapToArrayJson(map) {
      return JSON.stringify([...map]);
    }
    
    let myMap = new Map().set(true, 7).set({foo: 3}, ['abc']);
    mapToArrayJson(myMap)
    // '[[true,7],[{"foo":3},["abc"]]]'
    

    (6) JSON 지도 로 전환
    JSON 이 Map 으로 바 뀌 면 모든 키 이름 이 문자열 입 니 다.
    function jsonToStrMap(jsonStr) {
      return objToStrMap(JSON.parse(jsonStr));
    }
    
    jsonToStrMap('{"yes": true, "no": false}')
    // Map {'yes' => true, 'no' => false}
    
    

    그러나 JSON 전체 가 하나의 배열 이 고 각 배열 의 구성원 자체 가 두 명의 구성원 이 있 는 배열 이라는 특수 한 상황 이 있다.이 때 는 일일이 대응 해 맵 으로 전환 할 수 있다.이 는 종종 맵 이 배열 JSON 으로 바 뀌 는 역작 동 이다.
    function jsonToMap(jsonStr) {
      return new Map(JSON.parse(jsonStr));
    }
    
    jsonToMap('[[true,7],[{"foo":3},["abc"]]]')
    // Map {true => 7, Object {foo: 3} => ['abc']}
    

    4、 WeakMap
    보 세 요. 다음 에 나 눠 줄 친구 들 이 이 걸 나 눠 요.
    5. 왜 Set 와 Map 이 필요 합 니까?
    오랫동안 배열 은 자 바스 크 립 트 의 유일한 집합 유형 이 었 다.(그러나 일부 개발 자 들 은 비 배열 대상 도 집합 이 고 키 값 대 집합 에 불과 하 며 그들의 용도 와 배열 은 완전히 다르다 고 생각 합 니 다).JavaScript 배열 기능 은 다른 언어 와 같 지만 ECMAScript 6 표준 이 제정 되 기 전에 선택 할 수 있 는 집합 유형 이 제한 되 어 있 고 배열 은 색인 을 사용 하기 때문에 대기 열 과 스 택 을 만 드 는 데 자주 사 용 됩 니 다.개발 자 들 이 비수 치형 색인 을 사용 해 야 한다 면 비수 치형 대상 으로 필요 한 데이터 구 조 를 만 들 것 입 니 다. 이것 이 바로 Set 집합 과 Map 집합의 조기 실현 입 니 다.
    Set 집합 은 중복 요소 가 없 는 목록 입 니 다. 개발 자 들 은 배열 요 소 를 방문 하 는 것 처럼 모든 요 소 를 하나씩 방문 하지 않 습 니 다. 일반적인 방법 은 주어진 값 이 특정한 집합 에 존재 하 는 지 확인 하 는 것 입 니 다.이것들 이 바로 배열 과 Set, Map 의 본질 적 인 차이 이다.
    6, 지도 실전
    다 중 탭 전환 저장 내용 방안 구현
    여러 tab 를 전환 할 때 마지막 작업 의 역 사 를 유지 해 야 합 니 다.각 모듈 의 state 를 유지 해 야 합 니 다.이렇게 하면 모듈 입구 의 index 에서 state 와 서브 모듈 의 state 가 서로 관통 되 어야 합 니 다.현재 이 기능 이 있 는 모듈 은 [임무 센터], [학급 관리], [학생 관리], [교원 관리], [권한 관리], [과정 관리], [학원 관리] 를 포함한다.
    실현 방안 소개 (중심 사상)
    tab 마다 path 가 다 르 기 때문에 path 를 key 로 하고 state 를 value 로 map 를 만 듭 니 다.각 모듈 에 여러 개의 키 모듈 이 있 는 state 도 유지 해 야 하기 때문에 path+tag 을 key 로 확장 합 니 다.tag 의 값 은 원칙적으로 마음대로 정의 할 수 있 으 며, 숫자 로 확장 하 는 것 이 좋 습 니 다. 예 를 들 어 '1','_2','_3. 잠깐 만 요.[권한 관리] 트 리 모듈 에 tag='_tree' 이 있 습 니 다.[학원 관리] 있 습 니 다 tag='_1'. 서브 탭 의 type 에 따라 확인 할 수 있 습 니 다.
    사용 방법
    1. 새 state 와 저 장 된 state 를 합 칩 니 다.constructor 함수 에 코드 를 추가 해 야 합 니 다. this.state = util.BossTabMap.getSaveState(tag, this.state); this. state 가 초기 화 된 후에 야 합 니 다.경로 홈 페이지 라면 이렇게 사용 할 수 있 습 니 다. this.state = util.BossTabMap.getSaveState('', this.state);
    constructor(props) {
            super(props);
            ....................
            this.state = {
                list: [],
                pager: defaultPager,
                searchParams: searchParams,
                loading: false,
            };
            ............
            
            this.state = util.BossTabMap.getSaveState('',this.state);// tag
             :
            const tag='_1';
            this.state = util.BossTabMap.getSaveState(tag, this.state);
        }
    

    2. 현재 state 를 저장 합 니 다.render 의 state 만 이 마지막 작업 으로 남아 있 기 때문에 rander 에 코드 를 추가 합 니 다: util.BossTabMap.addSaveState('', this.state); 또는 util.BossTabMap.addSaveState(tag, this.state);
    render() {
            const self = this;
            ..........
            util.BossTabMap.addSaveState('_tree', this.state);
            return (
                
    ...........
    ); }

    핵심 코드
    파일 위치: / newboss_fe/src/spa/common/util/util.jsx
        /*
         * tab    。
         *       state    state:this.state = UTIL.BossTabMap.getSaveState('',this.state);
         *      state:util.BossTabMap.addSaveState('',this.state);
         *     :tag      。      。
         */
        ..........................
        BossTabMap: {
            tabsMap: new Map(),//     state
            tagArr: ['_tree', '_1', '_2', '_3', '_4', '_5'],//  tag
            getTag: function (path) {
                //   path  tag
                const self = this;
                const curTag = this.tagArr.filter(function (tag) {
                    return self.tabsMap.has(path + tag);
                });
                return curTag[0] || '';
            },
            setTag: function (vtag) {
                //   tag
                var tag = vtag || '';
                this.tagArr.push(tag);
            },
            getSaveState: function (tag, state) {
                //       state
                const path = location.hash + tag;
                if (this.tabsMap.has(path)) {
                    return Object.assign(state, this.tabsMap.get(path));
                }
                return state;
            },
            addSaveState: function (tag, state) {
            //   state
                const path = location.hash + tag;
                this.tabsMap.set(path, state);
            },
            delSaveTabs: function (path) {
                    //     tab  ,   map      state。
                    
                //  tag path     ?
                // const path = location.hash;
                // tag   _tree,'_1','_2'    path     tag
                const self = this;
                const tag = this.getTag(path);
                // console.log('delSaveTabs..tabsMap..start=', this.tabsMap);
                if (this.tabsMap.has(path)) {
                    self.tagArr.forEach((ctag) => {
                        // console.log('ctag=', (path+ctag));
                        const tpath = path + ctag;
                        if (self.tabsMap.has(tpath)) {
                            // console.log('tpath=', tpath);
                            self.tabsMap.delete(tpath);
                        }
                    })
                    self.tabsMap.delete(path);
                }
                // console.log('delSaveTabs..tabsMap..end=', this.tabsMap);
            },
            has: function (path) {
                if (this.tabsMap.has(path)) {
                    return true;
                }
                return false;
            },
            add: function (path, state) {
                this.tabsMap.set(path, state);
            },
            get: function (path) {
                return this.tabsMap.get(path);
            },
            del: function (path) {
                this.tabsMap.delete(path);
            }
        }
    

    좋은 웹페이지 즐겨찾기