红宝石散列比较值,并返回相同的结构

问题描述:

我有2个散列像这样:红宝石散列比较值,并返回相同的结构

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" 
    } 
} 
+0

什么是'hash'和'co mpared_hash'? – sawa 2015-03-03 01:26:24

+0

你的问题是什么? – sawa 2015-03-03 01:27:52

这应该为你工作:

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" 
#  } 
# } 

这是一种方式,你可以获得你想要的结果。

代码

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"}} 

我们只希望保留的new_hash[:values]如果new_hash[:values][k]是在值两散的一个关键kstored_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"] 

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

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

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"}} 

让我们确认时new_hash[:values]值被改变stored_hash不会改变:

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"}}