我正在尝试创建一个rake任务,该任务从模型中获取数据并生成类似en.yml
的区域设置文件。
例如,输入数据:
[
{a: {w: 0}, b: '2', c: '3'},
{a: {q: 1}},
{aa: {bb: {cc: '4'}}},
{aa: {bb: {ee: '4'}}}
]
输出数据应如下所示:
{
a: {w: 0, q: 1},
b: '2',
c: '3',
aa: {bb: {cc: '4', ee: '4'} }}
}
因此,应该对同一深层次上相同键的值进行分组。 我怎么能用ruby的数组和哈希方法呢?
答案 0 :(得分:1)
您可以对nasted哈希结构使用递归方法。
require 'yaml'
def group_by_keys(sub_hash, export)
sub_hash.each do |k, v|
if Hash === v
export[k] ||= {}
self.send(__method__, v, export[k])
else
export[k] = v
end
end
end
yaml = "[
{a: {w: 0}, b: '2', c: '3'},
{a: {q: 1}},
{aa: {bb: {cc: '4'}}},
{aa: {bb: {ee: '4'}}}
]"
imput = YAML.load(yaml)
export = imput.each_with_object({}){|sub_hash, exp| group_by_keys(sub_hash, exp)}
导出强>
p export
# {
# "a" => {"w" => 0, "q" => 1},
# "b" => "2",
# "c" => "3",
# "aa" => {
# "bb" => {"cc" => "4", "ee" => "4"}
# }
# }
我希望这会有所帮助
答案 1 :(得分:1)
Rails Active Support Core扩展,Hash#deep_merge
完成相同的工作。你可以利用那颗宝石,而不是重新发明轮子。
require "active_support/core_ext/hash"
arr = [
{a: {w: 0}, b: '2', c: '3'},
{a: {q: 1}},
{aa: {bb: {cc: '4'}}},
{aa: {bb: {ee: '4'}}}
]
p arr.reduce {|h1, h2| h1.deep_merge(h2)}
#=> {:a=>{:w=>0, :q=>1}, :b=>"2", :c=>"3", :aa=>{:bb=>{:cc=>"4", :ee=>"4"}}}
如果您不想使用gem,可以从Rails code base here复制deep_merge
的代码。
答案 2 :(得分:0)
# No gems needed, to scale however you'll need to add code
hash_array = [{a: {w: 0}, b: "2", c: "3"}, {a: {q: 1}}, {aa: {bb: {cc:"4"}}}, {aa: {bb: {ee: "4" }}}]
new_hash = {}
test_array = []
hash_array.each do |hashes|
if test_array.include?(hashes.keys[0])
if hashes.values[0].values[0].class == Hash
merge_this = hashes.values[0].values[0]
new_hash[hashes.keys[0]].values[0].merge!(merge_this)
else
new_hash[hashes.keys[0]].merge!(hashes.values[0])
end
else
new_hash.merge!(hashes)
end
test_array << hashes.keys[0]
end
# You can easily move braces into standard .yml format
p new_hash # returns {:a=>{:w=>0, :q=>1}, :b=>"2", :c=>"3", :aa=>{:bb=>{:cc=>"4", :ee=>"4"}}}