Ruby 用另一个哈希值填充哈希值
我有一个包含更多值的散列:Ruby 用另一个哈希值填充哈希值,ruby,Ruby,我有一个包含更多值的散列: hash1 = { :a => { :foo => 435, :bar => 3264 }, :b => { :foo => 45234, :bar => 2452 }, :c => { :foo => 4352, :bar => 4535 } } 我需要把a,b,c的和加到新的数组中 hash2 = { :a => total,
hash1 = {
:a => {
:foo => 435,
:bar => 3264
},
:b => {
:foo => 45234,
:bar => 2452
},
:c => {
:foo => 4352,
:bar => 4535
}
}
我需要把a,b,c的和加到新的数组中
hash2 = {
:a => total,
:b => total,
:c => total
}
到目前为止,我的尝试是:
hash2.each{e,v|v=hash1[0]}
挣扎,所以我需要一些帮助!谢谢 如果您使用的是Ruby版本>=2.4,您可以
hash2 = hash1.transform_values { |v| v.values.sum }
=>{:a=>3699, :b=>47686, :c=>8887}
更新感谢@3limin4t0r和@Aleksei Matiushkin为Ruby版本<2.4提供了一种更干净的方式,请参见注释
hash2 = Hash[hash1.map { |k, v| [k, v.values.reduce(0, &:+)] }]
=> {:a=>3699, :b=>47686, :c=>8887}
# or if your prefer each_with_object
hash1.each_with_object({}) { |(k, v), h| h[k] = v.values.reduce(0, &:+) }
=> {:a=>3699, :b=>47686, :c=>8887}
原稿留在这里进行对话
否则,你可以这样做,可能有一个更快的方法,但它的工作
hash2 = {}
sum_vals = hash1.values.map{|h| h.values.inject(&:+)}
hash1.keys.each_with_index{|key, i| hash2[key] = sum_vals[i] }
hash2
=>{:a=>3699, :b=>47686, :c=>8887}
是的,Aleksei Matiushkin完全正确<代码>转换_值具有破坏性版本和非破坏性版本。破坏性版本有一个被称为“爆炸”或感叹号的东西,因此:
transform\u值代码>被读取为转换值,它将改变原始哈希。另一方面,transform\u values
返回一个新数组,而不改变原始数组,因此是无损的。从我所能告诉你的,你想要处理非破坏性版本
在这种情况下,您可以运行一个hash1.transform_values{| values | values.values.sum}
,它将返回新的散列,但是,由于这是非破坏性的,hash1
仍将等于原始的hash1
。因此,您需要将hash2
设置为等于变换值
基本上,所发生的是散列正在运行与键相关联的所有值,并获取这些键值(由于您有一个多维散列),然后将它们相加
这里有一个很好的链接供您查看 hash1.transform_values{v | v.values.sum}
@AlekseiMatiushkin仅在ruby版本>=2上工作。4@lacostenycoder现在是2019年;如果有人问这样的问题,这显然意味着他们不支持遗留庞然大物,可以安装最新的ruby版本。@AlekseiMatiushkin,是真的,我是最新的,但ruby版本<2.4不支持它。对于较旧的版本,我会使用Hash[hash1.map{k,v |[k,v.values.reduce(0,:+)]]
@AlekseiMatiushkin让我们更进一步清理它hash1.每个带有对象({})的对象({})(k,v),h{h[k]=v.values.reduce(:+)}
@engineersmnky-我总是明确指定初始值和符号,以澄清意图(传递块)reduce
和inject
接受一个符号是完全错误的。@AlekseiMatiushkin,而我可以承认,将一个符号传递给reduce
确实会让人感觉有点脏:)。所有的答案都是建立在给定结构的基础上的,所以初始值既不在这里也不在那里。如果v
不是Hash
,那么values
消息的结果是不确定的,sum
或reduce
更是如此。例如,如果值
实际生成一个数组
或数组
,那么reduce(0,&:+)
将产生类型错误
(与求和
)但reduce(&:+)
不会。@lacostenycoder它在相同的假设下运行,灵活性较低<代码>求和
假定为整数
并且需要初始值,除非obj.all?(数值)
。这意味着,要利用与数字以外的东西的总和,您最了解该东西是什么,并且/或者传递一个块来转换该东西(本质上是map(&method).sum(initial)
)例如{foo:1,bar:2}.sum(&:pop)\=>3
但是{foo:1,bar:2}.sum(“,&:to#=>”[:foo,1][:bar,2]”
或{foo:1,bar:2}.sum([])#=>[:foo,1,:bar,2]