Ruby on rails Ruby:如何将多个JSON对象的值相加为一个对象?

Ruby on rails Ruby:如何将多个JSON对象的值相加为一个对象?,ruby-on-rails,json,ruby,Ruby On Rails,Json,Ruby,我有两个类似这样的JSON对象: object1 = { "Oct 2019": 100, "Nov 2019": 100, "Dec 2019": 100, "Jan 2020": 100, "Feb 2020": 100, "Mar 2020": 100, "Apr 2020": 100, "May 2020": 100, "

我有两个类似这样的JSON对象:

object1 = {
"Oct 2019": 100,
"Nov 2019": 100,
"Dec 2019": 100,
"Jan 2020": 100,
"Feb 2020": 100,
"Mar 2020": 100,
"Apr 2020": 100,
"May 2020": 100,
"Jun 2020": 100,
"Jul 2020": 100,
"Aug 2020": 100,
"Sep 2020": 100
}

object2 = {
"Oct 2019": 50,
"Nov 2019": 50,
"Dec 2019": 50,
"Jan 2020": 50,
"Feb 2020": 50,
"Mar 2020": 50,
"Apr 2020": 50,
"May 2020": 50,
"Jun 2020": 50,
"Jul 2020": 50,
"Aug 2020": 50,
"Sep 2020": 50
}
如何对
object1
object2
的值求和,使生成的json对象如下所示:

result = {
"Oct 2019": 150,
"Nov 2019": 150,
"Dec 2019": 150,
"Jan 2020": 150,
"Feb 2020": 150,
"Mar 2020": 150,
"Apr 2020": 150,
"May 2020": 150,
"Jun 2020": 150,
"Jul 2020": 150,
"Aug 2020": 150,
"Sep 2020": 150
}

(本例中的值每个月都是相同的,但在我的应用程序中它们都是不同的值。)

有很多方法可以做到这一点,但我发现最简单的方法是使用使用块的形式来计算出现在合并的两个散列中的键的值

object1.merge(object2) { |_k,v1,v2| v1+v2 }
  # = {:"Oct 2019"=>150, :"Nov 2019"=>150, :"Dec 2019"=>150,
  #    :"Jan 2020"=>150, :"Feb 2020"=>150, :"Mar 2020"=>150,
  #    :"Apr 2020"=>150, :"May 2020"=>150, :"Jun 2020"=>150,
  #    :"Jul 2020"=>150, :"Aug 2020"=>150, :"Sep 2020"=>150}
文档中定义了三个块变量,
\u k
v1
v2
。按照惯例,我在公共键(
\k
)的名称开头加了一个下划线,以向读者表明它未用于块计算


如果要组合三个或更多这样的哈希,请编写:

object1.merge(object2, object3, ...) { |_k,v1,v2| v1+v2 }

另一种方法非常简单:

keys = (object1.keys + object2.keys).uniq
  #=> [:"Oct 2019", :"Nov 2019",..., :"Sep 2020"]
keys.each_with_object({}) do |k,h|
  h[k] = object1.fetch(k,0) + object2.fetch(k,0)
end
  #=> {:"Oct 2019"=>150, :"Nov 2019"=>150,..., :"Sep 2020"=>150}

人们可以用
objectx[k].to_i
替换
objectx.fetch(k,0)
,作为
nil.to_i
,但我认为这读起来并不好


这可以扩展到以显而易见的方式对三个或更多散列求和。

有很多方法可以做到这一点,但我发现最简单的方法是使用一个块的形式来计算出现在合并的两个散列中的键的值

object1.merge(object2) { |_k,v1,v2| v1+v2 }
  # = {:"Oct 2019"=>150, :"Nov 2019"=>150, :"Dec 2019"=>150,
  #    :"Jan 2020"=>150, :"Feb 2020"=>150, :"Mar 2020"=>150,
  #    :"Apr 2020"=>150, :"May 2020"=>150, :"Jun 2020"=>150,
  #    :"Jul 2020"=>150, :"Aug 2020"=>150, :"Sep 2020"=>150}
文档中定义了三个块变量,
\u k
v1
v2
。按照惯例,我在公共键(
\k
)的名称开头加了一个下划线,以向读者表明它未用于块计算


如果要组合三个或更多这样的哈希,请编写:

object1.merge(object2, object3, ...) { |_k,v1,v2| v1+v2 }

另一种方法非常简单:

keys = (object1.keys + object2.keys).uniq
  #=> [:"Oct 2019", :"Nov 2019",..., :"Sep 2020"]
keys.each_with_object({}) do |k,h|
  h[k] = object1.fetch(k,0) + object2.fetch(k,0)
end
  #=> {:"Oct 2019"=>150, :"Nov 2019"=>150,..., :"Sep 2020"=>150}

人们可以用
objectx[k].to_i
替换
objectx.fetch(k,0)
,作为
nil.to_i
,但我认为这读起来并不好


这可以扩展到以明显的方式对三个或更多散列求和。

对于OP,值得注意的是,这(与大多数后缀方法一样)是一种变异操作-它改变了原始输入。如果要保留原始散列并返回一个新对象作为输出,只需
dup
it首先对其副本进行操作
object1.dup.update(…
@Chris,谢谢你的提醒。我将
update
更改为
merge
,以避免变异
object1
。对于OP,值得注意的是这(与大多数带有后缀的方法一样)是一种变异操作-它更改原始输入。如果要保留原始哈希并返回一个新对象作为输出,只需
dup
it首先对其副本进行操作。
object1.dup.update(…
@Chris,谢谢你的提醒。我将
update
改为
merge
以避免变异
object1
。这里没有JSON。JSON是文本定义,你可以使用a和键。
{a:1}
{a=>1}
的缩写,同样适用于你的日期。
{2019 10:100}
{:“2019年10月”=>100}
的缩写。请注意,一般来说,您应该避免使用动态符号,因为它们从不被垃圾收集。在处理日期时,使用字符串可能更合适。
{“2019年10月”=>100}
这里没有JSON。JSON定义为文本,您可以使用带键的a。
{a:1}
{:a=>1}
的缩写,同样适用于日期。
{“2019年10月”:100}
{:“2019年10月”=>100}
的缩写。请注意,一般来说,您应该避免使用动态符号,因为它们从不被垃圾收集。使用字符串处理日期时可能更合适。
{“2019年10月”=>100}