js 前端 实现双向映射(双向Map)

3,877 阅读1分钟

场景

假如后端传来数据

// 假如接口约定 0: 衣服,1: 裤子,2:  鞋
{
    type: 0
}

渲染时,需要将 type 由 0 映射为 衣服

const TPYE_MAP = {
    0: '衣服'
}

...
<span>
    { TPYE_MAP[type] }
</span>

发起请求时,需要将 type 由 衣服 映射为 0。这个场景下要怎么简单实现映射?

两个 map

const TPYE_NUM_TO_CHAR_MAP = {
    0: '衣服'
}
const TPYE_CHAR_TO_NUM_MAP = {
    '衣服': '0'
}

更好的实现

java中有个数据结构BiMap,用js实现下


class BiMap {
    constructor(map, inverseMap) {
        this.map = map;
        this.inverseMap = inverseMap;
    }

    static create() {
        return new BiMap(new Map(), new Map());
    }

    get size() {
        return this.map.size;
    }

    set(key, value) {
        const oldValue = this.map.get(key);
        this.inverseMap.delete(oldValue);
        this.map.set(key, value);
        this.inverseMap.set(value, key);
        return this;
    }

    clear() {
        this.map.clear();
        this.inverseMap.clear();
    }

    delete(key) {
        const value = this.map.get(key);
        const deleted = this.map.delete(key);
        const inverseDeleted = this.inverseMap.delete(value);

        return deleted || inverseDeleted;
    }

    entries() {
        return this.map.entries();
    }

    forEach(callbackFn, thisArg) {
        return this.map.forEach(callbackFn, thisArg);
    }

    get(key) {
        return this.map.get(key);
    }

    has(key) {
        return this.map.has(key);
    }

    keys() {
        return this.map.keys();
    }

    inverse() {
        return new BiMap(this.inverseMap, this.map);
    }

    values() {
        return this.inverseMap.keys();
    }

    *[Symbol.iterator]() {
        yield* this.map;
    }
}

使用

const TYPE_MAP = BiMap.create()
TYPE_MAP.set(0, '衣服')

console.log('TYPE_MAP正向:', TYPE_MAP.get(0)); // TYPE_MAP正向: 衣服
console.log('TYPE_MAP逆向: ', TYPE_MAP.inverse().get('衣服')); // TYPE_MAP逆向:  0