23

我在 python 上有一个简单的例子:

programs = {}
if not programs.has_key(( program, time )):
     programs[( program, time )] = 0
programs[( program, time )] = programs[( program, time )] + 1

如何在 Javascript 中使用数组作为键?

4

4 回答 4

42

这将“工作”。(但我不推荐)

var a = {};
var b = [1,2,3];    
a[b] = 'hello';

// a[b] evaluates to 'hello'
// a[[1,2,3]] evaluates to 'hello'
// a['1,2,3'] evaluates to 'hello'

它之所以有效,是因为当您将数组 [1,2,3] 作为散列(映射/关联数组)键传递时,在执行散列查找之前将被转换为字符串 '1,2,3'。只要您不需要两个具有相同值的不同数组来映射到不同的哈希值,它就应该满足您的需求。

var c = [1,2,3]
// a[c] evaluates to 'hello' even though we never executed a[c] = 'hello'
// but b == c evaluates to false
// b & c are two separate objects with the same values, so when they
// get converted to a string for hashing, they return the same value from the hash

如前所述,如果您想使用对象引用作为键,您需要的不仅仅是标准的 JavaScript 哈希。

更新

根据@speedplane 的评论:

我怀疑toString()当您将数组传递给哈希键时,JS 会调用它。因此,您可以轻松测试您实际将获得的密钥:

 ["x", "y", "z"].toString();                // 'x,y,z'
 ["x,y,z"].toString();                    // 'x,y,z'
 [1,2,3].toString();                      // '1,2,3'
 [1,2,'3'].toString();                    // '1,2,3'
 [[1],[2],[3]].toString();                // '1,2,3'
 [["x",1], ["y",2], ["z",3]].toString();  // 'x,1,y,2,z,3'

因此,我再次建议您不要这样做,除非您真的了解正在发生的事情。即使那样,我也不会这样做。

于 2012-04-16T12:29:05.357 回答
20

JavaScript 键是字符串。

您需要一个WeakMap, 或一个自定义方法来将数组映射到其他对象。

于 2012-04-16T12:23:09.697 回答
8

我编写了一个名为array-keyed-map的库,用于在现代 JavaScript 中稳健地执行此操作。与迄今为止发布的其他答案不同,它不依赖于将值序列化为字符串,而是使用 ES2015Map对象,它可以接受任意值作为键。

我将引用我对实现概述的不同问题的回答,因此如果库由于某种原因消失,或者您想自己实现它,该方法将被保留下来:

维护Map对象树。每棵树存储:

  • 在内部声明的Symbol键下:树中该点的值(如果有)。保证唯一性,因此Symbol没有用户提供的值可以覆盖此键。

  • 在它的所有其他键上:到目前为止所有其他从这棵树设置的下一个树。

例如,在 上akmap.set(['a', 'b'], true),内部的树形结构就像——</p>

'a':
  [value]: undefined
  'b':
    [value]: true

在那之后做akmap.set(['a'], 'okay')只会改变路径的值'a'

'a':
  [value]: 'okay'
  'b':
    [value]: true

要获取数组的值,请在从树中读取相应键的同时遍历数组。undefined如果任何点的树都不存在,则返回。[value]最后,从你得到的树上读取内部声明的 符号。

要删除数组的值,请执行相同操作,但删除[value]-symbol-key 下的所有值,并在递归步骤后删除任何以 asize为 0 的子树。


为什么是树?因为当多个数组具有相同的前缀时它非常有效,这在实际使用中非常典型,用于处理例如文件路径。

于 2019-04-08T07:48:09.367 回答
-2

这对你有用吗?

jsfiddle

<script>
var ary = {person1:'valerie', person2:'alex'};
for (key in ary) {
    document.write(key, '<br>')
}

document.write(ary['person2'], '<br>')
</script>
于 2012-04-16T12:28:44.817 回答