我是ruby的新手,正在寻找一种优雅的方式来对以下哈希进行排序。
哈希A:
a = { :metric1 => {
"Bob" =>10,
"Jane" =>15,
"Sally" =>20
},
:metric2 => {
"Jane" =>15,
"Bob" =>10,
"Sally" =>10
},
:metric3 => {
"Bob" =>10,
"Sally" =>10,
"Jane" =>5
}
}
哈希B:
b = { "Bob" => {
:metric1 =>10,
:metric2 =>10,
:metric3 =>10
},
"Jane" => {
:metric1 =>15,
:metric2 =>15,
:metric3 =>5
},
"Sally" => {
:metric1 =>20,
:metric2 =>10,
:metric3 =>10
}
}
基本上我想要一种简单的方法来迭代这个对象来输出一个像这样的表:
Metric 1 Metric 2 Metric 3
Bob 10 20 20
Jane 15 15 5
Sally 20 10 10
答案 0 :(得分:3)
功能方法(假设所有人都有相同的度量标准):
names = a.values.first.keys
b = Hash[names.map do |name|
[name, Hash[a.map { |metric, values| [metric, values[person]] }]]
end]
[编辑]第二种方法,可能比我的第一次尝试更正统。它使用Facets(因此对于那些不熟悉它所采用的新抽象的人来说,它看起来有点神秘)。但是,如果检查每个步骤的输出,则很容易:
triplets = a.flat_map { |metric, h| h.map { |name, value| [name, metric, value] } }
pairs_by_name = triplets.map_by { |name, metric, value| [name, [metric, value]] }
b = pairs_by_name.mash { |name, pairs| [name, pairs.to_h] }
答案 1 :(得分:2)
我更简单地做:
h = {}
a.each do |metric, hash|
hash.each do |name, value|
h[name] ||= {}
h[name][metric] = value
end
end
答案 2 :(得分:0)
这是一个功能更强大的答案。它处理一些名称只出现在某些哈希中的情况 - 假设Sally只出现在:metric3 - 尽管将nils放在结果哈希中
metrics = a.keys
names = a.values.map { |v| v.keys }.flatten.uniq
names.inject({}) do |memo, name|
memo[name] = metrics.inject({}) do |memo, metric|
memo[metric] = a[metric][name]
memo
end
memo
end