这是一个简单的方法:
posts.each_with_object(Hash.new { |h, k| h[k] = [] }) do |post, hash|
days_old = (Date.today - post.created_at.to_date).to_i
case days_old
when 0..39
hash[0] << post
when 40..59
hash[40] << post
when 60..89
hash[60] << post
when 90..Float::INFINITY # or 90.. in the newest Ruby versions
hash[90] << post
end
end
这将遍历帖子,以及具有default value of an empty array 的哈希。
然后,我们只需检查帖子创建的天数,并将其添加到哈希的相关键中。
在处理完所有帖子后返回此哈希。
你可以使用任何你想要的键(例如hash["< 40"]),尽管我使用你的分区来说明目的。
结果将类似于以下内容:
{ 0: [post_1, post_3, etc],
40: [etc],
60: [etc],
90: [etc] }
希望这会有所帮助 - 如果您有任何问题,请告诉我。
编辑:如果您的 PARTITIONS 来自外部来源,那就有点棘手了,尽管以下方法可行:
# transform the PARTITIONS into an array of ranges
ranges = PARTITIONS.map.with_index do |p, i|
return 0..(p - 1) if i == 0 # first range is 0..partition minus 1
return i..Float::INFINITY if i + 1 == PARTITIONS.length # last range is partition to infinity
p..(PARTITIONS[i + 1] - 1)
end
# loop through the posts with a hash with arrays as the default value
posts.each_with_object(Hash.new { |h, k| h[k] = [] }) do |post, hash|
# loop through the new ranges
ranges.each do |range|
days_old = Date.today - post.created_at.to_date
hash[range] << post if range.include?(days_old) # add the post to the hash key for the range if it's present within the range
end
end
最后的编辑:
使用each_with_object 有点傻,group_by 可以完美地处理这个问题。示例如下:
posts.group_by |post|
days_old = (Date.today - post.created_at.to_date).to_i
case days_old
when 0..39
0
when 40..59
40
when 60..89
60
when 90..Float::INFINITY # or 90.. in the newest Ruby versions
90
end
end