【问题标题】:How to create a consistent hashstring of a ruby array?如何创建 ruby​​ 数组的一致哈希字符串?
【发布时间】:2012-10-19 08:09:50
【问题描述】:

我想知道如何创建一个充满字符串的 ruby​​ 数组的一致哈希。要求是,如果数组包含相同的值,则哈希值始终相同,而与它们的顺序无关。

>> a = ["a", "b", "c", "d"]
>> SomeModule.hash(a)
=> "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed"
>>
>> b = ["d", "b", "c", "a"]
>> SomeModule.hash(b)
=> "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed"
>>
>> SomeModule.hash(a) == SomeModule.hash(b)
=> true

Zlib 或摘要只处理字符串,但我必须始终对数组进行排序并加入它才能使其正常工作。

那么还有什么更好的吗?

【问题讨论】:

    标签: ruby arrays hash zlib digest


    【解决方案1】:

    您可以将数组转换为 Set 并调用 to_set 方法(不要忘记 `require 'set')

    a = ["a", "b", "c", "d"]
    a.to_set.hash # => 425494174200536878
    
    b = ["d", "b", "c", "a"]
    b.to_set.hash # => 425494174200536878
    

    【讨论】:

    • 啊,这是一个完美的解决方案,谢谢。不知道 Ruby 中的 Set。非常合身!
    • 看起来很简单,但是你会丢失重复的数组元素。这样['a','b'] 将与['a','b','a'] 相同。
    • to_set.hash 方法在这里使用是否可靠并且不会随着其他 ruby​​ 1.9 版本而改变?
    • 我刚刚意识到.hash 方法只是表示运行时哈希,在多次运行期间并不一致。你有什么建议?
    • 只是取消选中这个作为正确答案,因为不幸的是它在程序的多次运行中并不是真的一致..
    【解决方案2】:

    您可以对数组进行排序,将所有元素连接到一个字符串并对其进行哈希处理。

    def hash(array)
       Digest::SHA1.digest(array.join)
    end
    

    【讨论】:

    • 我看到你最后一句话了。但是我不确定如果元素的顺序无关紧要,您是否会进行排序。
    • 如果将数组转换为集合,您将丢失重复元素ruby-doc.org/stdlib-1.9.3/libdoc/set/rdoc/Set.html。不知道这是不是你想要的。
    • 这是 - 在我的情况下 - 甚至是期望的行为,所以这是完全可以接受的。
    • 似乎,与 sort 一样,这是唯一真正“一致”的方法......所以谢谢!
    【解决方案3】:

    已经有一个名为set 的标准库引入了Set 类。您也可以轻松地自己实现它。而不是这样的数组:

    ["a", "b", "c", "d"]
    

    将其保存为哈希:

    {"a" => true, "b" => true, "c" => true, "d" => true}
    

    【讨论】:

      【解决方案4】:

      似乎.hash 的无状态方面被忽视了。运行以下方面考虑此问题的时间敏感性:

      a = %w(alpha bravo charlie delta echo foxtrot gulf hotel india july kilo sheep)
      c = %w(alpha bravo charlie delta echo foxtrot gulf hotel india july kilo sheep)
      
      require 'ap'
      
      ap a
      ap c
      
      def h2(value)
          Digest::SHA512.hexdigest value.inspect
      end
      
      aa = h2(a)
      cc = h2(c)
      ap aa
      ap cc
      
      ap "they are equal" if aa==cc
      puts
      
      t = Turtle.new("Tom", "blue")  # an object with two ivars, name and colour
      ap h2(t)
      
      t.name = "Teth"
      ap h2(t)
      
      t.name = "Tom"
      ap h2(t)
      puts
      
      t.colour = "ruby red"
      ap h2(t)
      
      t.colour = "blue"
      ap h2(t)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-07-24
        • 1970-01-01
        • 1970-01-01
        • 2020-06-05
        • 1970-01-01
        • 2016-02-27
        • 2012-11-23
        • 1970-01-01
        相关资源
        最近更新 更多