Ruby on rails 带散列的和数组
如何在这两个散列数组之间执行加法,例如,我想从第一个数组中提取第一个散列,然后求和Ruby on rails 带散列的和数组,ruby-on-rails,ruby,ruby-on-rails-3.2,Ruby On Rails,Ruby,Ruby On Rails 3.2,如何在这两个散列数组之间执行加法,例如,我想从第一个数组中提取第一个散列,然后求和number、s\u number、l\u number,如果从第二个数组中提取第一个散列,那么求和将取决于在处创建的,如果在第一个数组中创建的与在第二个数组中创建的相等,则执行+。请看一下我期望得到的回报,因为我不知道如何更好地解释这一点 多谢各位 raw_data = [ [ {"created_at"=>"2013-11-17","number"=>0,"s
number、s\u number、l\u number
,如果从第二个数组中提取第一个散列,那么求和将取决于在处创建的,如果在第一个数组中创建的与在第二个数组中创建的相等,则执行+
。请看一下我期望得到的回报,因为我不知道如何更好地解释这一点
多谢各位
raw_data = [
[
{"created_at"=>"2013-11-17","number"=>0,"s_number"=>0,"l_number"=>0},
{"created_at"=>"2013-11-18","number"=>6,"s_number"=>1,"l_number"=>4},
{"created_at"=>"2013-11-19","number"=>1,"s_number"=>1,"l_number"=>1},
{"created_at"=>"2013-11-20","number"=>0,"s_number"=>0,"l_number"=>0}
],
[
{"created_at"=>"2013-11-17","number"=>2,"s_number"=>3,"l_number"=>4},
{"created_at"=>"2013-11-18","number"=>1,"s_number"=>41,"l_number"=>1},
{"created_at"=>"2013-11-19","number"=>5,"s_number"=>45,"l_number"=>7},
{"created_at"=>"2013-11-20","number"=>7,"s_number"=>8,"l_number"=>2}
]
]
应该退还什么
[
{"created_at"=>"2013-11-17","number"=>2,"s_number"=>3,"l_number"=>4},
{"created_at"=>"2013-11-18","number"=>7,"s_number"=>42,"l_number"=>5},
{"created_at"=>"2013-11-19","number"=>6,"s_number"=>46"l_number"=>8},
{"created_at"=>"2013-11-20","number"=>7,"s_number"=>8,"l_number"=>2}
]
更新哈希格式与我发布的不同:
{:created_at=>Sun, 17 Nov 2013, :number=>0, :s_number=>0, :l_number=>0}
我会这样做:
result = raw_data.flatten.each_with_object({}) do |hash, result|
date = hash.delete("created_at")
result[date] = Hash.new(0) unless result[date]
hash.each{|key, val| result[date][key] += val}
end.map{|date, hash| hash["created_at"] = date; hash}
p result #=> [{"number"=>2, "s_number"=>3, "l_number"=>4, "created_at"=>"2013-11-17"}, ...
或者更好,因为它将保持哈希的顺序:
result = raw_data.flatten.group_by{|x|x["created_at"]}.values.map do |x|
x.inject do |result, hash|
result.merge(hash){|key, old, new| old.is_a?(String) ? old : old + new }
end
end
p result #=> [{"created_at"=>"2013-11-17", "number"=>2, "s_number"=>3, "l_number"=>4}, {"created_at"=>"2013-11-18", "number"=>7, "s_number"=>42, "l_number"=>5} ...
首先,需要对数组求和:
raw_data.sum
这将返回类似于:
[
{"created_at"=>"2013-11-17","number"=>0,"s_number"=>0,"l_number"=>0},
{"created_at"=>"2013-11-18","number"=>6,"s_number"=>1,"l_number"=>4},
{"created_at"=>"2013-11-19","number"=>1,"s_number"=>1,"l_number"=>1},
{"created_at"=>"2013-11-20","number"=>0,"s_number"=>0,"l_number"=>0}
{"created_at"=>"2013-11-17","number"=>2,"s_number"=>3,"l_number"=>4},
{"created_at"=>"2013-11-18","number"=>1,"s_number"=>41,"l_number"=>1},
{"created_at"=>"2013-11-19","number"=>5,"s_number"=>45,"l_number"=>7},
{"created_at"=>"2013-11-20","number"=>7,"s_number"=>8,"l_number"=>2}
]
现在,我们需要按“created_at”键对元素进行分组:
raw_data.sum.group_by{|element| element['created_at']}
这将导致:
{
"2013-11-17" => [
{"created_at"=>"2013-11-17","number"=>0,"s_number"=>0,"l_number"=>0},
{"created_at"=>"2013-11-17","number"=>2,"s_number"=>3,"l_number"=>4},
],
"2013-11-18" => [
{"created_at"=>"2013-11-18","number"=>6,"s_number"=>1,"l_number"=>4},
{"created_at"=>"2013-11-18","number"=>1,"s_number"=>41,"l_number"=>1}
], ...
}
我们只需要此散列的值:
raw_data.sum.group_by{|element| element['created_at']}.values
# =>
[
[
{"created_at"=>"2013-11-17","number"=>0,"s_number"=>0,"l_number"=>0},
{"created_at"=>"2013-11-17","number"=>2,"s_number"=>3,"l_number"=>4},
],
[
{"created_at"=>"2013-11-18","number"=>6,"s_number"=>1,"l_number"=>4},
{"created_at"=>"2013-11-18","number"=>1,"s_number"=>41,"l_number"=>1}
], ...
}
现在我们需要将每个散列数组映射到一个散列。为此,我们将使用块的注入和合并函数:
raw_data.sum.group_by{|element| element[:created_at]}.values.map{|a| a.inject({}) {|result, hash| result.merge(hash) {|key, old_value, new_value| key == :created_at ? old_value : old_value + new_value}}}
# =>
[
{"created_at"=>"2013-11-17","number"=>2,"s_number"=>3,"l_number"=>4},
{"created_at"=>"2013-11-18","number"=>7,"s_number"=>42,"l_number"=>5},
{"created_at"=>"2013-11-19","number"=>6,"s_number"=>46"l_number"=>8},
{"created_at"=>"2013-11-20","number"=>7,"s_number"=>8,"l_number"=>2}
]
output=[]
raw_data.flatte.group_by{x | x[:created_at].to_s}。每个do |键,值|
temp_hash={:created_at=>key.to_date}
[:编号,:s_编号,:l_编号]。每个do|attr|
temp|u hash[attr]=value.collect{w|w[attr]}.sum
结束
输出尝试下一个代码:
result = raw_data.flatten.group_by{|x|x["created_at"]}.values.map do |x|
x.inject do |result, hash|
result.merge(hash){|key, old, new| old.is_a?(String) ? old : old + new }
end
end
对于您提供的第一个答案数据,我得到了以下错误:Date不能强制为Fixnum
,对于第二个:预期为数字
,因此如果日期存储为日期而不是字符串,请将最后一个答案中的old.is_a?(string)
更改为old.is_a?(Date)我这样做了,但做了一些奇怪的事情:[{“created\u at”:“2013-11-17”,“编号”:103,“s_编号”:102,“l_编号”:87}]
这就是你从上述原始数据中得到的吗?这看起来真的很奇怪?有人知道吗?我想问题出在这里,我从另一个地方获取了数组格式,显然,这就是我的日期发送方式<代码>{:created_at=>Sun,2013年11月17日,:number=>0,:s_number=>0…}
如果您在irb
中运行上述代码,那么您可能会得到未定义的方法sum,但它在rails控制台中工作。如果您想在纯ruby中运行它,那么只需将sum
替换为reduce(:+)
liketemp_hash[attr]=值。收集{w | w[attr]}。reduce(:+)
如果您得到的是未定义的方法sum
或+
,那么您的哈希值必须是{u在2013-11-18”,“number”=>“7”处创建的字符串,“s|u number”=>“42”、“l|u number”=>“5”}
。如果这是问题所在,那么您可以简单地使用temp|u hash[attr]=值。收集{w | w[attr]。to|i}.sum
或temp|u hash[attr]=值。收集{w | w[attr]。to|i}.reduce(:)
现在正在为散列中的每个元素返回null。请检查我的更新。谢谢没有将数组隐式转换为散列
我现在得到了这个…预期的数字
我昨天也遇到了同样的情况,请检查此链接:>
def sum_two_arrays_of_hashes(raw_data, keys = %w[number s_number l_number])
raw_data[0].map.with_index do |item, index|
if raw_data[1][index]["created_at"] = item["created_at"]
sum_hash = {}
sum_hash["created_at"] = item["created_at"]
sum_hash.merge keys.inject({}){ |m, k| m[k] = raw_data[1][index][k] + item[k]; m}
end
end
end
result = raw_data.flatten.group_by{|x|x["created_at"]}.values.map do |x|
x.inject do |result, hash|
result.merge(hash){|key, old, new| old.is_a?(String) ? old : old + new }
end
end