【问题标题】:Hashmaps in javascript from integer keysjavascript中的哈希图来自整数键
【发布时间】:2010-06-26 12:18:39
【问题描述】:

我正在用 javascript 编码,我需要 HashMap 类型结构。 通常当我需要 hashmaps 时,我只会使用关联数组(以字符串作为键)。 但这次我需要整数作为哈希映射的键。

因此,如果我尝试存储 A[1000]=obj,则会创建 1001 大小的数组并将 A[1001] 作为 obj。 即使我尝试 A["1000"]=obj ,它仍然会分配 1001 个空格并用 undefined 填充它们。

我不希望这样,因为我的钥匙可能非常大(大约 1 磨)。 我可以将它用作 A["dummy1000"]=obj 但我不想使用这种肮脏的方法。

无论如何也可以优雅而轻松地做到这一点?

【问题讨论】:

  • 是什么让您认为它分配了所有空间?

标签: javascript hashmap


【解决方案1】:

执行A[1000] = 1 不会创建包含 1000 个元素的数组。它创建了一个长度属性为 1001 的数组对象,但这只是因为 JavaScript 数组中的长度属性被定义为最大索引 + 1。

这样做的原因是你可以这样做for(var i = 0; i < A.length; i++)

我看到您对数组的分配感到困惑。在您看来,JavaScript 似乎已经用 undefined 填充了元素 - 实际上那里没有任何东西,但是如果您尝试访问尚未定义的数组中的任何元素,您会得到 undefined

【讨论】:

  • 所以你的意思是说,即使我做 A[1000000]=1 ,实际上分配的内存不是按顺序排列的,而是只有几个字节。 &因此在实际运行网络期间使用 A[1000000] 是安全的吗?
  • 当然。试试看。试试A[100000000] = 1 看看你使用的内存是否比A[0] = 1 多。
  • 这也是为什么在这个稀疏的“伪数组”上的许多操作(例如迭代)会比在小而密集的数组上慢得多的原因;小数组或仅使用 push 增长的数组。
【解决方案2】:

从键创建一个哈希码,并将其用作索引。将哈希码限制在一个很小的范围内,这样你就可以得到一个相当小的桶数组。

类似:

function HashMap() {
  // make an array of 256 buckets
  this.buckets = [];
  for (var i = 0; i < 256; i++) this.buckets.push([]);
}

HashMap.prototype.getHash = function(key) {
  return key % 256;
}

HashMap.prototype.getBucket = function(key) {
  return this.buckets[this.getHash(key)];
}

HashMap.prototype.getBucketItem = function(bucket, key) {
  for (var i = 0; i < bucket.length; i++) {
    if (bucket[i].key == key) return i:
  }
  return -1;
}

HashMap.prototype.setItem = function(key, value) {
  var bucket = this.getBucket(key);
  var index = this.getBucketItem(bucket, key);
  if (index == -1) {
    bucket.push({ key: key, value: value });
  } else {
    bucket[index].value = value;
  }
}

HashMap.prototype.getItem = function(key) {
  var bucket = this.getBucket(key);
  var index = this.getBucketItem(bucket, key);
  if (index == -1) {
    return null;
  } else {
    return bucket[index].value;
  }
}

免责声明:代码未经测试。

【讨论】:

  • 你到底为什么要这么麻烦?
  • 有一个现有的 JS HashMap 实现,由我编写:code.google.com/p/jshashtable
  • @Pointy:例如,如果您需要使用一些不能在常规数组中使用的键。
  • 我非常喜欢这段代码。这个HashMap 很简单,它使用数组作为后备存储,(理论上)对其执行许多操作比使用标准JS 对象执行adddelete 操作要快得多。它的内存占用也比@TimDown 的版本小得多。想看一个关于这个的jsperf。由于buckets 数组可能非常稀疏,您可能需要考虑storing all set indices in a BitField,或者更好的是动态增长/收缩。
猜你喜欢
  • 2014-05-11
  • 1970-01-01
  • 2015-07-07
  • 2011-04-10
  • 1970-01-01
  • 1970-01-01
  • 2013-05-02
  • 2012-06-26
  • 2011-12-03
相关资源
最近更新 更多