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

时间:2012-04-16 12:21:03

标签: javascript

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

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

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

4 个答案:

答案 0 :(得分:22)

这将“有效”。 (但我不推荐它)

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]作为哈希(map / associative-array)键传递时,在执行哈希查找之前将其转换为字符串'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的评论:

我怀疑JS在将数组传递给哈希键时会调用toString()。因此,您可以轻松地测试您将要获得的内容作为您的密钥:

 ["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'

所以,我建议你不要这样做,除非你真的了解正在发生的事情。即便如此,我也不会这样做。

答案 1 :(得分:13)

JavaScript密钥是字符串。

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

答案 2 :(得分:2)

这会为你做到这一点吗?

jsfiddle

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

document.write(ary['person2'], '<br>')
</script>

答案 3 :(得分:1)

我已经编写了一个名为array-keyed-map的库,用于在现代JavaScript中可靠地完成此操作。与到目前为止发布的其他答案不同,它不依赖于将值序列化为字符串,而是使用ES2015 Map对象,该对象可以接受任意值作为键。

我将引述my answer to a different question的实现概述,以便保留该方法的后代,以防万一由于某种原因该库消失了,或者您想自己实现它:

  

维护一个Map对象的树。每棵树都存储:

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

  •   
  • 在所有其他键上:到目前为止,所有其他已设置的下一棵树。

  •   
     

例如,在akmap.set(['a', 'b'], true)上,内部树   结构就像-

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

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

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

要获取数组的值,请在读取时迭代数组   树上相应的键。如果树返回undefined   在任何时候都不存在。最后,阅读内部声明的   [value]符号从您已经走到树上。

     

要删除数组的值,请执行相同的操作,但删除所有值   在[value]-符号键下,然后删除所有子树。   递归步骤,如果它们的size最终为0。

     
     

为什么要树?因为当多个数组具有   相同的前缀,这在实际使用中非常典型,   与文件路径。