Javascript 映射,键中有两个值

问题描述 投票:0回答:8

我的页面上有 3 个下拉菜单,第三个下拉菜单中的选项取决于前两个下拉菜单中的选择。

所以我想知道是否有办法在javaScript中用二维键实现地图?就像

<Key1, Key2> -> Value

我认为一种简单的方法是将两个键连接成一个字符串。有没有更体面的办法?

谢谢。

javascript
8个回答
5
投票

您可以拥有一个包含更多对象的对象:

var options = {
    'option 1': {
        'option 1.1': [
            'option 1.1.1',
            'option 1.1.2',
            'option 1.1.3',
            'option 1.1.4'
        ],
        'option 1.2': [
            'option 1.2.1',
            /* etc. */
};

然后,您将访问第三个下拉列表的选项

options[firstSelectedValue][secondSelectedValue]


编辑:这也是一个演示,使用一些新功能,如果您使用 Internet Explorer 8 或更低版本浏览,则可能需要实现这些新功能:)


2
投票

连接两个键有什么问题?您所需要的只是确保连接的键是唯一的,我想这可以通过使用两个键中任何一个都不使用的字符分隔两个值来轻松实现。


2
投票

我正在寻找类似的数据结构,但找不到。我一直在使用 TypeScript,所以我开发了一个使用 TypeScript 的解决方案。

export class TwoMapKey<T> {
    private __map__: object;

    constructor() {
        this.__map__ = new Object();
        this.get = this.get.bind(this);
        this.set = this.set.bind(this);
        this.remove = this.remove.bind(this);
        this.keys = this.keys.bind(this);
        this.nestedKeys = this.nestedKeys.bind(this);
        this.clear = this.clear.bind(this);
    }

    public get(key: string, nestedKey: string): T {
        if (!this.__map__[key] || this.__map__[key] && !this.__map__[key][nestedKey])
            return;

        return this.__map__[key][nestedKey];
    }

    public set(key: string, nestedKey: string, value: T): void {
        if (!this.__map__[key]) {
            this.__map__[key] = new Object();
        }

        Object.defineProperty(this.__map__[key], nestedKey, { value: value, configurable: true, enumerable: true });
    }

    public remove(key, nestedKey): void {
        if (!this.__map__[key]) {
            return;
        }

        delete this.__map__[key][nestedKey];
    }

    public keys(): string[] {
        return Object.getOwnPropertyNames(this.__map__);
    }

    public nestedKeys(): Array<string[]> {
        return Object.getOwnPropertyNames(this.__map__).map(key => Object.keys(this.__map__[key]));
    }

    public clear(): void {
        Object.getOwnPropertyNames(this.__map__).forEach(property => {
            delete this.__map__[property];
        });
    } }

您可以简单地使用两个键创建地图,如下所示:

let twoKeyMap = new TwoKeyMap<any>();
twoKeyMap.set('mainKey1', 'nestedKey1', {value: 'value'});

它不如 HashMap 高效。您应该能够轻松地在 ES6 或 ES5 中进行相同的转换。


0
投票

没有其他办法。 JS 地图是普通对象,因此键与属性名称相同。即使您尝试使用例如。数组作为键,它将被转换为字符串。您应该将此字符串与一些特殊字符连接起来或将值存储在数组中,并在每次访问时扫描它。


0
投票

您可以通过使用 ES6 语法将两个键作为键数组添加到哈希对象上来实现此目的。然后您可以使用数组过滤器和正则表达式进行搜索:

const key1 = "key1";
const key2 = "key2";
const value = "whatever";

const hashObject = {};
const firstEntry = [key1, key2];
const secondEntry = [key2, key1];
const entryValue = { value };

hashObject[firstEntry] = entryValue;
hashObject[secondEntry] = entryValue;

const regByFirstKey = new RegExp(`${key1},.`);
const regBySecondKey = new RegExp(`.,${key2}`);

const keysArray = Object.keys(hashObject);

const resultByFirstKey = (keysArray.filter((key) => regByFirstKey.test(key)))[0];
const resultBySecondKey = (keysArray.filter((key) => regBySecondKey.test(key)))[0];

resultByFirstKey ? console.log(hashObject[resultByFirstKey].value) : undefined;
resultBySecondKey ? console.log(hashObject[resultBySecondKey].value) : undefined;

0
投票

具有两个键的 Map 可以被认为是一个图,其中两个键是节点,它们之间有一条边。

class Graph {
  nodes = new Map();

  addNode(ref) {
    if (!this.nodes.has(ref)) {
      this.nodes.set(ref, new Map());
    }
  }

  addEdge(ref1, ref2, value) {
    this.nodes.get(ref1)?.set(ref2, value);
    this.nodes.get(ref2)?.set(ref1, value);
  }

  getEdge(ref1, ref2) {
    return this.nodes.get(ref1)?.get(ref2);
  }
}

const graph = new Graph();

graph.addNode('left');
graph.addNode('right');
graph.addEdge('left', 'right', 12345);

console.log(graph.getEdge('left', 'right')); // 12345
console.log(graph.getEdge('right', 'left')); // 12345

您甚至可以通过在

addEdge
方法本身中创建不存在的节点来使其变得更简单。


0
投票

JS 没有提供开箱即用的方法。具有连接字符串键的对象或 ES6 映射很脆弱,并且可能会失败,具体取决于您的分隔符。

地图允许非字符串/符号作为键。但数组键不起作用:

  • 默认查找函数将通过引用比较数组键,而不是值。
  • 无法指定自定义查找函数。
  • 不存在不可变的元组类型。 (尽管有提案添加此内容)

最安全的选择是像

Map<K1, Map<K2, V>>
这样的嵌套地图,使用方式如下:

const map = new Map();

function set(key1, key2, val) {
  if (!map.has(key1)) {
    map.set(key1, new Map());
  }
  map.get(key1).set(key2, val);
}

function get(key1, key2) {
  return map.get(key1)?.get(key2);
}

-2
投票

您可以将键设置为数组。只需创建您的数组

[key1, key2];
然后将该值设置为您的键并将其与您的值相关联。

obj[[key1,key2]] = "my value";

这是一个 jsFiddle http://jsfiddle.net/TwQLW/

© www.soinside.com 2019 - 2024. All rights reserved.