【问题标题】:Generic 2D hash in JavaScript?JavaScript中的通用2D哈希?
【发布时间】:2015-07-07 00:10:27
【问题描述】:

在其他语言中,可以创建通用 2D 散列。我知道在 javascript 中也可以创建 2d 哈希 as explained here,但我似乎无法找到实现此目的的通用方法。

作为我正在寻找的一个例子。在 Ruby 中,您可以这样做:

2dhash = Hash.new{|h, k| h[k] = Hash.new }

puts 2dhash["test"]["yes"]
#=> nil
2dhash[1][2] = "hello"
puts 2dhash[1][2]
#=> "hello"

请注意,我还没有初始化第二级哈希,它是自动发生的。

是否有可能在 javascript 中以某种方式实现相同的目标?具体来说,一种无需初始化第一级散列(或将其硬编码为更具体)即可制作二维散列的方法。 2dhash 将被动态使用,所以我不知道第一级是什么。

【问题讨论】:

    标签: javascript multidimensional-array hash


    【解决方案1】:

    看起来不错的数据结构练习,让我试试吧:D

    function Hash() {
      this.hash = {};
    }
    
    Hash.prototype.set = function(val) {
      var paths = Array.prototype.slice.call(arguments, 1) // all levels
      var path = paths.shift() // first level
      var hashed = this.hash[path]
    
      if (paths.length) {
        // still have deeper levels
        if (!(hashed instanceof Hash)) {
          hashed = this.hash[path] = new Hash()
        }
        Hash.prototype.set.apply(hashed, [val].concat(paths))
      } else {
        // last level
        this.hash[path] = val
      }
    }
    
    Hash.prototype.get = function() {
      var paths = Array.prototype.slice.call(arguments, 0) // all levels
      var path = paths.shift() // first level
      var hashed = this.hash[path]
    
      if (paths.length) {
        // still have deeper levels
        return Hash.prototype.get.apply(hashed, paths)
      } else {
        // last level
        return hashed
      }
    }
    

    现在,让我们看看它是否有效:

    var trytry = new Hash()
    trytry.set('the value to store', 'key1', 'key2')
    
    trytry.get('key1')         // Hash{key2: 'the value to store'}
    trytry.get('key1', 'key2') // 'the value to store'
    

    万岁,它有效!

    它也适用于更深层次:

    trytry.set('the value to store', 'key1', 'key2','key3', 'key4')
    trytry.get('key1', 'key2','key3') // Hash{key4: 'the value to store'}
    

    但是,这种方法的一个缺点是您必须使用实例方法 getset,而不是原生对象字面量 getter/setter。

    它仍然不完整。对于生产环境,我们需要做更多的事情,例如方法和属性,如containssize 等。

    【讨论】:

    • 太棒了@Leo!比我使用__noSuchMethod__ 建议的要好得多。
    • @Cort3z 这只是一个练习,如果你想在生产环境中使用,你可能需要使用containssize等方法和属性来改进它。:D
    • 是的,确实如此。当您访问不存在的密钥时,我也在考虑可能会有一些不同的行为。我认为如果它是 level1 值返回一个空的哈希值会很好,如果它是 level2+ 则返回 null/undefined。
    【解决方案2】:

    如果你用对象初始化第一级哈希,那么你可以在没有 typeErrors 的情况下引用第二级,即使之前没有定义数据。

    例子:

    var _2dhash = {a: {}, b: {}, c:{}} 
    //Note you cannot start variable names with numbers in js
    _2dhash['a']['missingElement'];
    // > undefined
    

    之所以有效,是因为您正在访问已定义对象的未定义属性。如果您尝试通过缺少的顶级对象进行访问,即。

    _2dhash['d']['whatever'];
    

    你会得到一个 TypeError,因为 _2dhash.d 没有定义,第二次查找失败,试图读取 undefined 的 'whatever' 属性。

    【讨论】:

    • 也许我有点不清楚,我会更新问题,但我正在寻找一种不需要我初始化第一级哈希的方法。它将被动态使用,因此我无法知道该级别将是什么。
    • @Cort3z 恐怕你不能这样做 - 请参阅我编辑的详细说明。
    • 因此,如果我们挂钩到对象的__noSuchMethod__ 属性,也许可以实现。嗯..我会调查的。
    • @Cort3z 你会在这条路上遇到问题。首先,该 API 已过时/非标准,查找失败是针对未定义对象,而不是您的哈希对象。
    猜你喜欢
    • 1970-01-01
    • 2013-01-17
    • 2014-03-03
    • 2016-08-04
    • 1970-01-01
    • 1970-01-01
    • 2011-10-01
    • 1970-01-01
    • 2010-10-02
    相关资源
    最近更新 更多