【问题标题】:How to compare two Hashes so to return true if both Hashes have same keys/values?如果两个哈希具有相同的键/值,如何比较两个哈希以返回 true?
【发布时间】:2012-07-31 03:21:42
【问题描述】:

我正在使用 Ruby on Rails 3.2.2 和 Ruby 1.9.3。我想比较两个Hashes(AB),如果HashA)包含另一个HashB)的所有键/值,则返回true )。

例如,假设我有

params.inspect
# => { "action"=>"...", "controller"=>"...", "key_param1"=>"value_param1", , "key_param2"=>"value_param2", "key_param3"=>"value_param3", ... }

my_hash1.inspect
# => { "key_param1"=>"value_param1", "key_param2"=>"value_param2" }

my_hash2.inspect
# => { "key_param4"=>"value_param4", "key_param1"=>"value_param1" }

my_hash3.inspect
# => {}

然后我正在寻找一种方法(或类似的东西)来制作

params.has_same_keys_and_values_as?(my_hash1)
# => true

params.has_same_keys_and_values_as?(my_hash2)
# => false

params.has_same_keys_and_values_as?(my_hash3)
# => true

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 hash compare


    【解决方案1】:

    假设 Hash#keys 和 Hash#values 以相同的顺序返回值:

    params.values_at(*my_hash.keys) == my_hash.values
    

    【讨论】:

    • 假设 Hash#keys 和 Hash#values 以相同的顺序返回值,可以做些什么来实现呢?
    • params.values_at(*my_hash.keys.sort) == my_hash.values_at(*my_hash.keys.sort)
    • 如果我们不使用散列,对两个集合进行排序并一一比较它们的元素将是有益的。散列的优点是我们可以快速查看一个值是否存在,因此我们可以跳过排序,只需遍历其中一个散列中的每个元素。
    【解决方案2】:

    我认为你可以使用:

    a.slice(*b.keys) == b
    

    其中 a 和 b 是您的哈希值。请注意, slice 是一种 rails 方法,而不是 ruby​​。 用纯红宝石你可以写:

    a.keep_if{|k, v| b[k]} == b
    

    【讨论】:

    【解决方案3】:
    class Hash
      def >=(b)  
        eq = true
        b.each { |k, v| eq &= !(self.include? k) ? false : ( ( ((self[k]&&v).is_a? Hash) && !((v||self[k]).empty?) ) ? self[k]>=v : true)}
    
        return eq
      end
    
    end
    params = { "action"=>"...", "controller"=>"...", "key_param1"=>"value_param1", "key_param2"=>"value_param2", "key_param3"=>"value_param3" }
    my_hash1 = { "key_param1"=>"value_param1", "key_param2"=>"value_param2" }
    my_hash2 = { "key_param4"=>"value_param4", "key_param1"=>"value_param1" }
    my_hash3 = {}
    
    p params >= my_hash1 #true
    p params >= my_hash2 #false
    p params >= my_hash3 #true
    

    它也适用于“深度”哈希:

    b = {1 => {2 => {} }, 4 => {} }
    a = {1 => {2 => {3 => {} }}, 4 => {}, 5 => "123" }
    
    p a >= b #true
    p b >= a #false
    

    附:
    Whether one hash includes another hash

    【讨论】:

      【解决方案4】:

      编辑:这是假设值/键在两个哈希中的顺序不同。

      您可以遍历 hash1 中的每个键并使用 has_key?在哈希 2 上。请记住,这是一种幼稚的解决方案,对于大型数据集可能会很慢。

      结帐 has_key?和has_value?这里:http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-has_key-3F

      你可以循环如下:

      hash1.each_key { |key|
          if hash2.has_key?(key)
              do whatever
          endif
      }
      

      【讨论】:

        【解决方案5】:

        更好的方法,有一个积极的支持方法,hash.diff,用.empty 包装它?检查它们是否相同

        {:one => 1}.diff({:one => 1}).empty?
        
        => true
        
        {:one => 1}.diff({:one => 2}).empty?
        
        => false
        

        http://as.rubyonrails.org/classes/ActiveSupport/CoreExtensions/Hash/Diff.html

        【讨论】:

          猜你喜欢
          • 2016-03-11
          • 1970-01-01
          • 1970-01-01
          • 2019-05-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-09-05
          相关资源
          最近更新 更多