我有一个结构就是这样的数组:
{"status": "ok", "data": [{"temp": 22, "wind": 351.0, "datetime": "20160815-0330"}, {"temp": 21, "wind": 321.0, "datetime": "20160815-0345"}]}
我希望按datetime
键分组(忽略时间),找到最大temp
和平均wind
。
我尝试了以下内容,但不确定如何在同一张地图中执行max_by和average:
@data['data'].group_by { |d| d.values_at("datetime") }.map { |_, v| v.max_by { |h| h["temp"] } }
答案 0 :(得分:1)
因此,当您执行data
时,@data[:data].group_by { |data| data[:datetime].split('-')[0] }
实际上会变成符号,而不是字符串,因此您需要执行以下操作:
:datetime
为了按-
键分组,忽略时间部分(我假设,时间部分只是{"20160815"=>[{:temp=>22, :wind=>351.0, :datetime=>"20160815-0330"}, {:temp=>21, :wind=>321.0, :datetime=>"20160815-0345"}]}
之后的所有内容)。然后你最终看起来像哈希:
:temp
并找到您可以执行的:wind
的最大results = @data[:data].group_by { |data| data[:datetime].split('-')[0] }.map do |date, values|
[date, {
maximum_temp: values.max_by { |value| value[:temp] }[:temp],
average_wind: values.sum { |value| value[:wind] }.to_f / values.length
}]
end.to_h
# => {"20160815"=>{:maximum_temp=>22, :average_wind=>336.0}}
和平均值:
Objects
答案 1 :(得分:0)
上面的方法效果很好,使用 max_by 并访问值 [:temp] 然后求和和显式 to_h 即可。因此,如果您考虑到性能和良好的可读性,您可以使用基本的每个,如下所示,
data = {"20160815"=>[{:temp=>22, :wind=>351.0, :datetime=>"20160815-0330"}, {:temp=>21, :wind=>321.0, :datetime=>"20160815-0345"}]}
data.map do |k, v|
winds = []
temps = []
v.each do |item|
winds << item[:wind]
temps << item[:temp]
end
{k => {max_temp: temps.max, avg_wind: winds.inject(:+).to_f/winds.length}}
end
输出低于,
# => {"20160815"=>{:max_temp=>22, :avg_wind=>336.0}}
以下是使用 each和max_by 之间的小基准,
data = {"20160815"=>[{:temp=>22, :wind=>351.0, :datetime=>"20160815-0330"}, {:temp=>21, :wind=>321.0, :datetime=>"20160815-0345"}]}
def by_each(data)
data.map do |k, v|
winds = []
temps = []
v.each do |item|
winds << item[:wind]
temps << item[:temp]
end
{k => {max_temp: temps.max, avg_wind: winds.inject(:+).to_f/winds.length}}
end
end
def by_max(data)
data.map do |date, values|
[date, {
maximum_temp: values.max_by { |value| value[:temp] }[:temp],
average_wind: values.sum { |value| value[:wind] }.to_f / values.length
}]
end.to_h
end
Benchmark.ips do |x|
x.config(times: 10)
x.report 'BY_EACH' do
by_each(data)
end
x.report 'BY_MAX' do
by_max(data)
end
x.compare!
end
基准o / p如下所示,
Warming up --------------------------------------
BY_EACH 18.894k i/100ms
BY_MAX 13.793k i/100ms
Calculating -------------------------------------
BY_EACH 226.160k (± 5.3%) i/s - 1.134M in 5.025488s
BY_MAX 154.745k (± 5.8%) i/s - 772.408k in 5.006365s
Comparison:
BY_EACH: 226159.5 i/s
BY_MAX: 154744.8 i/s - 1.46x slower
因此,您可以看到BY_MAX比BY_EACH慢1.46倍。但是,当然,您可以使用任何适合您的理解和可用性的方法。