代码之家  ›  专栏  ›  技术社区  ›  CrazySynthax

节点:如何把对象作为散列对象的键?

  •  1
  • CrazySynthax  · 技术社区  · 6 年前

    class Node {
        constructor(num) {
            this.num = num;
            this.right = null;
            this.left = null;
        }
    }
    
    let node1 = new Node(1);
    let node2 = new Node(2);
    let hash = {};
    hash[node1] = 1;
    console.log(hash[node2]);  // prints "1" ????
    

    为什么hash[node2]返回值1? 哈希中只存储了node1。。。

    3 回复  |  直到 6 年前
        1
  •  3
  •   Lee Brindley    6 年前

    如果你记录你的对象,你会得到:

    { '[object Object]': 1 }

    因此,为什么下面的日志是1,因为node2被解释为[object]

    console.log(hash[node2]); //This is evaluating hash['object Object'] (Again)
    

    为了解决这个问题,有很多方法,其中之一是使用jsonapi对对象进行字符串化,并使用返回值作为键。

    例如。

    hash[JSON.stringify(node1)] = 1;
    

    现在你得到的是:

    {'{"num":1,"right":null,"left":null}': 1 }
    

    hash[node2] === undefined; //true
    hash[JSON.stringify(node2)] === undefined; //true
    

    您可能希望围绕此创建一个小API。举个很粗略的例子:

    class Hash {
    
        constructor () {
            this.hashes = {};
        }
    
        get (key) {
            return this.hashes[JSON.stringify(key)];
        }
    
        set (key, value) {
            this.hashes[JSON.stringify(key)] = value;
        }
    }
    
    const hashStore = new Hash();
    
    hashStore.set({foo: 'bar'}, 1);
    
    hashStore.set({foo: 'cheese'}, 2);
    
    console.log(hashStore.get({foo: 'bar'})); // 1
    console.log(hashStore.get({foo: 'cheese'})); //2
    

    这两种方法的后备方法都是“唯一性”,对于任何一种稳定的方法,您都希望为每个对象引入一个唯一的键,如果您使用Jakub Keller的方法,您将在toString覆盖中使用该唯一键。

    这两种方法都满足一系列的需求,如果您要存储文本,一个不同对象的数组作为键,我可能会使用我的方法,让API在get方法中存储的每个对象上写一个自定义的、唯一的ID,这同样不是完美的,因为您可能会覆盖现有的键。

        2
  •  2
  •   Jakub Keller    6 年前

    值显示为 1 [object Object] . 因此,你的关键是 .

    toString 并通过调用 托斯特林 :

    class Node {
        constructor(num) {
            this.num = num;
            this.right = null;
            this.left = null;
        }
    
        toString() {
            return this.num;
        }
    }
    
    let node1 = new Node(1);
    let node2 = new Node(2);
    let hash = {};
    hash[node1] = 1;
    console.log(hash[node2.toString()]);
    // output: 2
    
        3
  •  0
  •   Alan Alright    6 年前

    你可以用对象.assign()哈希对象的方法,如下所示:

    hash = Object.assign({node1, node2}, {});