我需要根据created_at日期以2周的增量显示调查结果。输出应该像这样:
{10/1:410/15: 610/29: 3}
…其中第一周是从调查回复中最早的created_at日期创建的,最后一周也是如此,但最晚的created_at。我见过像group_by{ |s| s.created_at.month}
这样的东西,但不是每隔一周就出现一次,从每周的周一开始。任何帮助将非常感激!
您可以计算当前记录和最旧记录之间的天数,然后使用模数14:
oldest_date = YourModel.minimum(:created_at).to_date
your_relation.group_by { |record|
(record.created_at.to_date - oldest_date).modulo(14)
}
可以定义一个返回年份和星期范围的方法,例如:
def by_year_and_by_two_weeks(my_date)
wk = my_date.strftime("%W").to_i/2
wks = [wk, wk.odd? ? wk+1 : wk - 1].sort # <== adjust this
[my_date.year, wks]
end
rails中的%W
使用星期一作为一周的第一天。
那么,当你有对象时:
object.created_at #=> 2021-09-19 08:58:16.78053 +0200
by_year_and_by_two_weeks(object.created_at) #=> [2021, [17, 18]]
则可以使用该方法进行分组。
objects.group_by { |d| by_year_and_by_two_weeks(d.created_at) }
这是一个值转换后的结果,使其可读的例子:
{[2021, [20, 21]]=>[2021-10-14 09:00:17.421142 +0200, 2021-10-15 09:00:17.421224 +0200, 2021-10-06 09:00:17.421276 +0200, 2021-10-10 09:00:17.421328 +0200], [2021, [18, 19]]=>[2021-09-22 09:00:17.421385 +0200]}
当然你可以改变by_year_and_by_two_weeks
的返回值,因为它最适合你。
您的要求:
- 从双周开始的星期一分组
- 你想要哈希键
我还将添加另一个未来的要求:
- 开始和结束日期可以在任何地方,甚至跨年边界。
如果我们接受这些要求,然后利用spickermann的modulo
思想,我们可以这样构建它:
start_date = first_item.created_at.to_date.prev_occurring(:monday)
your_items.group_by { |item|
item_date = item.created_at.to_date
days_from_start = item_date - start_date
biweekly_offset = days_from_start.modulo(14)
biweekly_monday = item_date - biweekly_offset
biweekly_monday
}
的例子:
test_dates = [
Date.new(2021, 10, 1),
Date.new(2021, 10, 6),
Date.new(2021, 10, 10),
Date.new(2021, 10, 13),
Date.new(2021, 10, 20),
Date.new(2021, 10, 31)
]
start = test_dates.first.prev_occurring(:monday)
pp test_dates.group_by { |date|
days_from_start = date - start
biweekly_offset = days_from_start.modulo(14)
biweekly_monday = date - biweekly_offset
biweekly_monday
}
输出:{ Mon, 27 Sep 2021 => [Fri, 01 Oct 2021, Wed, 06 Oct 2021, Sun, 10 Oct 2021],
Mon, 11 Oct 2021 => [Wed, 13 Oct 2021, Wed, 20 Oct 2021],
Mon, 25 Oct 2021 => [Sun, 31 Oct 2021] }