节点:如何将对象作为哈希对象的键?

问题描述 投票:1回答:3

请查看以下代码段:

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存储在哈希中...

javascript node.js
3个回答
3
投票

如果你记录你的对象你得到这个:

{ '[object Object]': 1 }

因此,为什么以下记录1,因为node2被解释为[object Object]

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

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

EG

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

现在你拥有的是:

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

因此,正如预期的那样,访问hash [node2]现在将是未定义的。

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在其答案中指出的那样,您可以覆盖Node类的toString函数。

这两种方法的后退都是“唯一性”,要么两种方法都是一种稳定的方法,你要为每个对象引入一个唯一的密钥,如果你使用Jakub Keller的方法,你就会在toString中使用那个唯一的密钥覆盖。

这两种方法都满足一组需求,如果你要存储文字,一组不同的对象作为你的键,我可能会采用我的方法,并让API为存储在get中的每个对象写一个自定义的唯一ID。方法,再次不完美,因为你可以覆盖现有的密钥。


2
投票

该值显示为1,因为任一对象的哈希在技术上是[object Object]。因此,你的关键是[object Object]

尝试重写Node类的toString并通过调用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

0
投票

您可以在哈希对象上使用Object.assign()方法,如下所示:

hash = Object.assign({node1, node2}, {});
© www.soinside.com 2019 - 2024. All rights reserved.