0

如果我有一系列月份,例如:

["05", "06", "07", "08", "09", "10", "11", "12", "01", "02", "03", "04", "05"]

以及一个月值和month_sum的散列:

[{"month"=>5, "month_sum"=>20}, {"month"=>4, "month_sum"=>100}]

如何将哈希合并到数组中,以便得到类似的东西?

[{"05" => 20}, {"07" => 0}, {"08" => 0}, {"09" => 0}, {"10" => 0}, {"11" => 0}, {"12" => 0}, {"01" => 0}, {"02" => 0}, {"03" => 0}, {"04" => 100}, {"05" => 0}, {"06" => 0}]

编辑

月份数组生成自:

date_from  = Date.parse(params[:search][:date_from])
date_to    = Date.parse(params[:search][:date_to])
date_range = date_from..date_to

date_months = date_range.map {|d| Date.new(d.year, d.month, 1) }.uniq
@date_range = date_months.map {|d| d.strftime "%m" }

所以需要注意的是,如果范围超过了,比如两年,数组将有重复的月份值。我想我需要将年份添加到该数组中?

有一个更好的方法吗?

这里的最终目标是为 highcharts 获取哈希或数组,以显示特定车辆的每月燃料使用总量。(只是让你有一些背景)。

4

1 回答 1

3

试试这个。请注意,最终产品是散列,而不是散列数组。但我认为在这种情况下哈希更容易使用。

# starting variables
array_of_months = ["05", "06", "07", "08", "09", "10", "11", "12", "01", "02", "03", "04", "05"]
month_sums = [{"month"=>5, "month_sum"=>20}, {"month"=>4, "month_sum"=>100}]

# clean up array_of_months
months = array_of_months.compact.sort
=> ["01", "02", "03", "04", "05", "05", "06", "07", "08", "09", "10", "11", "12"]

# compress month_sums into single key/value pairs such that first value becomes the key and second value becomes the value
sums = month_sums.inject({}) { |a, ms| a.merge!("%02d" % ms['month'] => ms['month_sum']) }
=> { "05" => 20, "04" => 100 }

# generate hash of all months and match sums value if key is present otherwise assign value zero
all_month_sums = months.inject({}) { |h, m| h.merge!(m => sums[m] || 0) }
=> {"01"=>0, "02"=>0, "03"=>0, "04"=>100, "05"=>20, "06"=>0, "07"=>0, "08"=>0, "09"=>0, "10"=>0, "11"=>0, "12"=>0}

编辑(根据新信息)

# starting variables
months = ["05", "06", "07", "08", "09", "10", "11", "12", "01", "02", "03", "04", "05"]
month_sums = [{"month"=>5, "month_sum"=>20}, {"month"=>4, "month_sum"=>100}, {"month" => 5, "month_sum" => 99 }]

# iterate each month, select the first match, remove the match when done. if no match just give month a zero.
months.inject([]) do |a, month|
  if s = month_sums.select { |s| month.to_i == s['month'] }.first
    a << { "%02d" % s['month'] => s['month_sum'] }
    s['month'] = nil
  else
    a << { month => 0 }
  end
  a
end
=> [{"05"=>20}, {"06"=>0}, {"07"=>0}, {"08"=>0}, {"09"=>0}, {"10"=>0}, {"11"=>0}, {"12"=>0}, {"01"=>0}, {"02"=>0}, {"03"=>0}, {"04"=>100}, {"05"=>99}]
于 2013-06-17T17:13:45.457 回答