2015-10-16 72 views
2

假设我正在访问图形数据结构中的节点。当我访问每个节点时,我会将其添加到“已访问”列表中。希望有一个O(1)查找来验证我不会多次访问同一个节点。当然,如果每个节点都有一个关联的值,我可以使用常规的JavaScript对象(散列表)来存储我的“已访问”列表,但是假设我想知道节点是否可以评估为字符串或不。是否有支持O(1)查找对象的JavaScript数据结构?我怎么能实现一个?具有O(1)查找的对象的数据结构?

+0

然后使用ES2015 ['Set'](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Set)(或['WeakMap'](https:// developer。 mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/WeakMap)无论哪个更合适) – zerkms

+0

你可以推送到一个数组并使用array.indexOf来查看一个节点ref是否在列表中,但这可能很慢。你也可以在节点本身设置一个看不见的道具,这很快,但可能会根据设置而破坏。 – dandavis

+0

@zerkms我刚刚检查我的公司授权的浏览器对兼容性列表[这里](http://kangax.github.io/compat-table/es6/)并哭了一下:'( – Blackhawk

回答

4

您可以使用SetWeakMap在ES2015都增加。

而且您不需要等待浏览器支持,因为像babel这样的转换器具有符合标准的polyfills。

+0

@jOshT它已经在答案。 – zerkms

0

要做O(1)查找,您需要使用哈希集。本地javascript中没有哈希集,但是有一个哈希映射(纯文本对象)。您可以通过检查对象是否包含密钥来模拟哈希集合。您的价值需要实施toString方法。

var Set = function() {} 
Set.prototype.contains = function (v) { 
    return (v.toString() in this); 
} 
Set.prototype.add = function (v) { 
    this[v.toString()] = true; 
} 
Set.prototype.remove = function (v) { 
    delete this[v.toString()]; 
} 
+0

这打破了该集与每个节点的值不可知的情况。假设我提供这个图结构作为API的一部分。如果有人在每个节点中存储几MB文本(我知道,不太可能,但是幽默我),依靠它作为散列键将是非常低效的。我宁愿剪掉中间人,也要使用物体的一些固有属性。每个JavaScript引擎都知道对象的等价性'obj1 === obj2',所以我认为即使它今天没有公开,也可以实现这些功能。 – Blackhawk

+0

你可以使用你想要的任何散列方法。底线是哈希方法必须返回一个字符串。你甚至可以把一个整数作为一个字符串。 – twinlakes

+0

另外,javascript引擎不知道等价。如果两个比较对象是同一个对象,则实际返回'==='。证明:在控制台中尝试'({a:1})===({a:1})''。如果你想要等价的话,给每个元素分配一个唯一的ID,并将其作为一个字符串从你的哈希方法(我选择调用'toString')返回 – twinlakes

相关问题