Ruby 如何对哈希中所有深度嵌套的值求和
我有一个类似于:Ruby 如何对哈希中所有深度嵌套的值求和,ruby,hash,sum,Ruby,Hash,Sum,我有一个类似于: hash = {"0"=>{"0"=>"148", "1"=>"2", "2"=>"90", ....}, "1"=>{"0"=>10}, .....} 我想添加其所有深度嵌套的值。将所有价值相加的最佳方法是什么 我试着这样做: hash.values.inject(0){|m,n| m + n.values.map(&:to_i).sum} 对于从您的解决方案派生的最多两级嵌套: hash = {"0"=>{"0"=>
hash = {"0"=>{"0"=>"148", "1"=>"2", "2"=>"90", ....}, "1"=>{"0"=>10}, .....}
我想添加其所有深度嵌套的值。将所有价值相加的最佳方法是什么
我试着这样做:
hash.values.inject(0){|m,n| m + n.values.map(&:to_i).sum}
对于从您的解决方案派生的最多两级嵌套:
hash = {"0"=>{"0"=>"148", "1"=>"2", "2"=>"90"}, "1"=>{"0"=>10}}
hash.values.inject(0) { |m, n|
Hash === n ? m + n.values.map(&:to_i).reduce(&:+) : m + n.to_i
}
#⇒ 250
def sum_deeply(h)
h.values.inject(0) { |m, v|
m + (Hash === v ? sum_deeply(v) : v.to_i)
}
end
sum_deeply(hash)
#⇒ 250
无限嵌套解决方案:
hash = {"0"=>{"0"=>"148", "1"=>"2", "2"=>"90"}, "1"=>{"0"=>10}}
hash.values.inject(0) { |m, n|
Hash === n ? m + n.values.map(&:to_i).reduce(&:+) : m + n.to_i
}
#⇒ 250
def sum_deeply(h)
h.values.inject(0) { |m, v|
m + (Hash === v ? sum_deeply(v) : v.to_i)
}
end
sum_deeply(hash)
#⇒ 250
希望有帮助。对于从您的解决方案衍生的最多两层嵌套:
hash = {"0"=>{"0"=>"148", "1"=>"2", "2"=>"90"}, "1"=>{"0"=>10}}
hash.values.inject(0) { |m, n|
Hash === n ? m + n.values.map(&:to_i).reduce(&:+) : m + n.to_i
}
#⇒ 250
def sum_deeply(h)
h.values.inject(0) { |m, v|
m + (Hash === v ? sum_deeply(v) : v.to_i)
}
end
sum_deeply(hash)
#⇒ 250
无限嵌套解决方案:
hash = {"0"=>{"0"=>"148", "1"=>"2", "2"=>"90"}, "1"=>{"0"=>10}}
hash.values.inject(0) { |m, n|
Hash === n ? m + n.values.map(&:to_i).reduce(&:+) : m + n.to_i
}
#⇒ 250
def sum_deeply(h)
h.values.inject(0) { |m, v|
m + (Hash === v ? sum_deeply(v) : v.to_i)
}
end
sum_deeply(hash)
#⇒ 250
希望有帮助。求解任意深度与求解固定深度没有太大区别:递归的简单应用。如果当前值是散列,则求和并将其添加到总数中,如果不是,则添加值本身
def hash_sum(h)
h.values.inject(0) do |total, value|
case value
when Hash then total + hash_sum(value)
else
total + value.to_i
end
end
end
求解任意深度与求解固定深度没有太大区别:这是递归的直接应用。如果当前值是散列,则求和并将其添加到总数中,如果不是,则添加值本身
def hash_sum(h)
h.values.inject(0) do |total, value|
case value
when Hash then total + hash_sum(value)
else
total + value.to_i
end
end
end
根据注释和示例,我假设所有相关值都正好位于深度2
hash = {"0"=>{"0"=>"148", "1"=>"2", "2"=>"90"}, "1"=>{"0"=>10}}
hash.values.flat_map(&:values).map(&:to_i).inject(:+)
# => 250
如果在深度3处有所有值,则添加另一个平面贴图&:值:
根据注释和示例,我假设所有相关值都正好位于深度2
hash = {"0"=>{"0"=>"148", "1"=>"2", "2"=>"90"}, "1"=>{"0"=>10}}
hash.values.flat_map(&:values).map(&:to_i).inject(:+)
# => 250
如果在深度3处有所有值,则添加另一个平面贴图&:值:
下面是一个递归方法,它是Frederick的一个变体:
def deep_hash(obj)
return obj.to_i unless obj.is_a? Hash
obj.reduce(0) { |t,(_,v)| t + deep_hash(v) }
end
hash = { "0"=>{ "0"=>"148, "1"=>"2", "2"=>"90" },
"1"=>{ "0"=>10, "1"=>{ "0"=>16 } } }
deep_hash(hash)
#=> 266
下面是一个递归方法,它是Frederick的一个变体:
def deep_hash(obj)
return obj.to_i unless obj.is_a? Hash
obj.reduce(0) { |t,(_,v)| t + deep_hash(v) }
end
hash = { "0"=>{ "0"=>"148, "1"=>"2", "2"=>"90" },
"1"=>{ "0"=>10, "1"=>{ "0"=>16 } } }
deep_hash(hash)
#=> 266
你的散列是否保证深度只有2?你的散列是否保证深度只有2?这是不一致的。inject和reduce是彼此的别名。为什么要同时使用这两个别名?@sawa的原因与两个别名存在的原因相同。第一个操作实际上是注射,而后者是减少。我确信,这是非常一致的,在这种情况下,我会拒绝更改命名。只是澄清一下:第二个代码片段中有reduce,这显然是错误的,我更改了它。第一个代码段中的reduce和inject都是故意存在的,这是不一致的。inject和reduce是彼此的别名。为什么要同时使用这两个别名?@sawa的原因与两个别名存在的原因相同。第一个操作实际上是注射,而后者是减少。我确信,这是非常一致的,在这种情况下,我会拒绝更改命名。只是澄清一下:第二个代码片段中有reduce,这显然是错误的,我更改了它。第一个代码段中的reduce和inject都是故意存在的。