我有一个辅助模块来生成数组哈希数据,类似于:
[{:date => d, :total_amount => 31, :first_category => 1, :second_category => 2,...},
{:date => d+1, :total_amount => 31, :first_category => 1, :second_category => 2,...}]
所以我制作的方法如下:
def records_chart_data(category = nil, start = 3.weeks.ago)
total_by_day = Record.total_grouped_by_day(start)
category_sum_by_day = Record.sum_of_category_by_day(start)
(start.to_date..Time.zone.today).map do |date|
{
:date => date,
:total_amount => total_by_day[date].try(:first).try(:total_amount) || 0,
Category.find(1).title => category_sum_by_day[0][date].try(:first).try(:total_amount) || 0,
Category.find(2).title => category_sum_by_day[1][date].try(:first).try(:total_amount) || 0,
Category.find(3).title => category_sum_by_day[2][date].try(:first).try(:total_amount) || 0,
}
end
end
由于类别将始终更改,我尝试在此方法中使用循环,如:
def records_chart_data(category = nil, start = 3.weeks.ago)
total_by_day = Record.total_grouped_by_day(start)
category_sum_by_day = Record.sum_of_category_by_day(start)
(start.to_date..Time.zone.today).map do |date|
{
:date => date,
Category.all.each_with_index do |category, index|
category.title => category_sum_by_day[index][date].try(:first).try(:total_amount) || 0,
end
:total_amount => total_by_day[date].try(:first).try(:total_amount) || 0
}
end
end
但是红宝石警告我一个错误:
/Users/tsu/Code/CashNotes/app/helpers/records_helper.rb:10: syntax error, unexpected tASSOC, expecting keyword_end
category.title => category_sum_by_day[index][d...
为什么会说expecting keyword_end
,我应该如何解决?
它调用的方法category_sum_by_day
如下:
def self.sum_of_category_by_day(start)
records = where(date: start.beginning_of_day..Time.zone.today)
records = records.group('category_id, date(date)')
records = records.select('category_id, date, sum(amount) as total_amount')
records = records.group_by{ |r| r.category_id }
records.map do |category_id, value|
value.group_by {|r| r.date.to_date}
end
end
或者我应该改变这个方法来为上面的助手生成一个更友好的方法吗?
答案 0 :(得分:2)
Category.all.each_with_index do |category, index|
category.title => category_sum_by_day # ...snip!
end
不幸的是,这段代码并不符合Ruby的语法。问题是块体。 x => y
不是表达式,语法要求块体是表达式。
如果您想一次按一个键值对生成哈希,请尝试以下Hash::[]
,Array#flatten
和splat运算符(即一元*
)的组合:< / p>
Hash[*5.times.map { |i| [i * 3, - i * i] }.flatten]
因此,我会更多或更少地重写records_chart_data
的最后一次表达,如下所示
(start.to_date..Time.zone.today).map do |date|
categories = Hash[*Category.all.each_with_index do |category, index|
[ category.title, category_sum_by_day[...] ]
end .flatten]
{ :date => date,
:total_amount => total_by_day[date].try(:first).try(:total_amount) || 0
}.merge categories
end
如果你认为它不可读,你可以用一种不太复杂的方式来做,即:
(start.to_date..Time.zone.today).map do |date|
hash = {
:date => date,
:total_amount => total_by_day[date].try(:first).try(:total_amount) || 0
}
Category.all.each_with_index do |category, index|
hash[category.title] = category_sum_by_day[...]
end
hash
end
另一个想法是使用Array#reduce
并采用更具功能性的方法。
(start.to_date..Time.zone.today).map do |date|
Category.all.each_with_index.reduce({
:date => date,
:total_amount => total_by_day[date].try(:first).try(:total_amount) || 0
}) do |hash, (category, index)|
hash.merge category.title => category_sum_by_day[...]
end
hash
end