Ruby比较哈希值并返回相同的结构

时间:2015-03-03 01:21:05

标签: ruby

我有两个哈希像这样:

stored_hash = {
   :name    => "hash_1",
   :version => "1.0",
   :values  => {
     :value_1 => "some_value",
     :value_2 => "some_other_value",
     :value_3 => "a_new_value",
     ...
     :value_x => "some_x_value"
   }
}

compare_hash = {
  :name    => "hash_2",
  :version => "2.0",
  :values  => {
    :different_1 => "some_value",
    :different_2 => "some_other_value",
    :different_3 => "a_new_value",
    ...
    :different_x => "some_x_value"
  }
}

我在这两个哈希的:values键中找到了常见值:

same_values = hash[:values].values & compared_hash[:values].values

一旦我得到它,我想返回一个类似于' stored_hash'的新哈希值,但它的:values包含我之前找到的same_values。

例如,如果两个哈希值都有"some_value""some_other_value""a_new_value",则我的新哈希值应如下所示:

new_hash = {
  :name    => "hash_1",
  :version => "1.0",
  :values  => {
    :value_1 => "some_value",
    :value_2 => "some_other_value",
    :value_3 => "a_new_value"
  }
}

2 个答案:

答案 0 :(得分:1)

这应该适合你:

stored_hash = {
   :name    => "hash_1",
   :version => "1.0",
   :values  => {
     :value_1 => "some_value",
     :value_2 => "some_other_value",
     :value_3 => "a_new_value",
     :value_x => "some_a_value"
   }
}

compare_hash = {
  :name    => "hash_2",
  :version => "2.0",
  :values  => {
    :different_1 => "some_value",
    :different_2 => "some_other_value",
    :different_3 => "a_new_value",
    :different_x => "some_b_value"
  }
}

common_values = compare_hash[:values].values & stored_hash[:values].values
new_hash = stored_hash.dup
new_hash[:values] = {}
common_values.each_with_index do |value, index |
    new_hash[:values]["value_#{index+1}".to_sym] = value
end
new_hash
# => new_hash = {
#      :name    => "hash_1",
#      :version => "1.0",
#      :values  => {
#      :value_1 => "some_value",
#      :value_2 => "some_other_value",
#      :value_3 => "a_new_value"
#      }
#   }

答案 1 :(得分:1)

这是获得所需结果的一种方式。

<强>代码

require 'set'

def make_new_hash(stored_hash, compare_hash)
  new_hash = stored_hash.dup
  compare_values =
    (stored_hash[:values].values & compare_hash[:values].values).to_set
  values_hash = new_hash[:values]
  keys_to_keep = values_hash.keys.select { |k|
    compare_values.include?(values_hash[k])}
  new_hash[:values] =
    Hash[keys_to_keep.zip(values_hash.values_at(*keys_to_keep))]
  new_hash
end

示例

stored_hash = {
   :name    => "hash_1",
   :version => "1.0",
   :values  => {
     :value_1 => "some_value",
     :value_2 => "some_other_value",
     :value_3 => "a_new_value",
     :value_x => "some_x_value"
   }
}

compare_hash = {
  :name    => "hash_2",
  :version => "2.0",
  :values  => {
    :different_1 => "some_value",
    :different_2 => "a_new_value",
    :different_3 => "some_strange_value",
    :different_x => "some_x_value"
  }
}

请注意,我在问题中给出的stored_hash进行了一些小改动。

make_new_hash(stored_hash, compare_hash)
  #=> {:name=>"hash_1", :version=>"1.0",
  #    :values=>{:value_1=>"some_value", :value_3=>"a_new_value",
  #    :value_x=>"some_x_value"}} 

<强>解释

创建stored_hash的副本:

new_hash = stored_hash.dup
  #=> {:name=>"hash_1", :version=>"1.0",
  #    :values=>{:value_1=>"some_value",
  #              :value_2=>"some_other_value",
  #              :value_3=>"a_new_value",
  #              :value_x=>"some_x_value"}}

如果k是哈希new_hash[:values]和哈希new_hash[:values][k]中的值之一,我们只想保留stored_hash[:values]的密钥compare_hash[:values],所以我们获得了这些价值观:

compare_values =
  (stored_hash[:values].values & compare_hash[:values].values).to_set
  # => #<Set: {"some_value", "a_new_value", "some_x_value"}>

我选择将它们保存在一个集合中以加速查找和获取唯一值。也可以将它们保存到数组中,如下所示:

(stored_hash[:values].values & compare_hash[:values].values).uniq
  #=> ["some_value", "a_new_value", "some_x_value"]

如果使用数组而不是集合,则后面的代码是相同的。

要简化,让我们创建一个变量:

values_hash = new_hash[:values]
  #=> {:value_1=>"some_value", :value_2=>"some_other_value",
  #    :value_3=>"a_new_value", :value_x=>"some_x_value"} 

接下来确定我们希望保留的New_hash[:values]的键:

keys_to_keep = values_hash.keys.select { |k|
  compare_values.include?(values_hash[k])}
  #=> [:value_1, :value_3, :value_x] 

保留除:value_2以外的所有密钥。由于comparative_hash[:values]没有值"some_other_value",因此未保留该密钥。

我们现在可以构建new_hash[:values]的更新值:

new_hash[:values] =
  Hash[keys_to_keep.zip(values_hash.values_at(*keys_to_keep))]
  #=> {:value_1=>"some_value", :value_3=>"a_new_value",
  #    :value_x=>"some_x_value"} 

最后,我们返回new_hash

new_hash
  #=> {:name=>"hash_1", :version=>"1.0",
  #    :values=>{:value_1=>"some_value", :value_3=>"a_new_value",
  #    :value_x=>"some_x_value"}} 

我们确认,stored_hash的值更改后,new_hash[:values]不会更改:

new_hash[:values][:value_1] = 'cat'
new_hash
  #=> {:name=>"hash_1", :version=>"1.0",
  #    :values=>{:value_1=>"cat", :value_3=>"a_new_value",
  #    :value_x=>"some_x_value"}} 
stored_hash
  #=> {:name=>"hash_1", :version=>"1.0",
  #    :values=>{:value_1=>"some_value", :value_2=>"some_other_value",
  #    :value_3=>"a_new_value", :value_x=>"some_x_value"}}