gpt4 book ai didi

ruby - 按月和年将 Ruby 日期数组分组为哈希

转载 作者:数据小太阳 更新时间:2023-10-29 08:14:29 25 4
gpt4 key购买 nike

假设我有一个 Date 的 Ruby 数组,例如:

2011-01-20
2011-01-23
2011-02-01
2011-02-15
2011-03-21

创建按年然后按月对日期元素进行分组的哈希的一种简单且类似 Ruby 的方法是什么,例如:

{
2011 => {
1 => [2011-01-20, 2011-01-23],
2 => [2011-02-01, 2011-02-15],
3 => [2011-03-21],
}
}

我可以通过遍历所有内容并提取年、月等,然后合并它们来做到这一点。

Ruby 为 Arrays 和 Hashes 提供了如此多的方法和 block ,一定有更简单的方法吗?

最佳答案

require 'date'

dates = [
'2011-01-20',
'2011-01-23',
'2011-02-01',
'2011-02-15',
'2011-03-21'
].map{|sd| Date.parse(sd)}

Hash[
dates.group_by(&:year).map{|y, items|
[y, items.group_by{|d| d.strftime('%B')}]
}
]
#=> {2011=>{"January"=>[#<Date: 2011-01-20 (4911163/2,0,2299161)>, #<Date: 2011-01-23 (4911169/2,0,2299161)>], "February"=>[#<Date: 2011-02-01 (4911187/2,0,2299161)>, #<Date: 2011-02-15 (4911215/2,0,2299161)>], "March"=>[#<Date: 2011-03-21 (4911283/2,0,2299161)>]}}

我注意到您已将月份名称更改为数字,因此您可能希望将上面的 d.strftime('%B') 替换为 d.month 或其他任何内容.

这是一个逐步的解释:

您基本上需要两级分组:第一级按年,第二级按月。 Ruby 有一个非常有用的方法 group_by,它根据给定的表达式(一个 block )对元素进行分组。所以:第一部分是按 year 对原始数组进行分组:

hash_by_year = dates.group_by(&:year)
# => {2011=>[#<Date: 2011-01-20 (4911163/2,0,2299161)>, #<Date: 2011-01-23 (4911169/2,0,2299161)>, #<Date: 2011-02-01 (4911187/2,0,2299161)>, #<Date: 2011-02-15 (4911215/2,0,2299161)>, #<Date: 2011-03-21 (4911283/2,0,2299161)>]}

这给了我们第一层:键是年份,值是给定年份的日期数组。但我们仍然需要对第二层进行分组:这就是我们按年 HashMap 的原因 - 按 month 对其值进行分组。让我们开始忘记 strftime 并假设我们按 d.month 分组:

hash_by_year.map{|year, dates_in_year|
[year, dates_in_year.group_by(&:month)]
}
# => [[2011, {1=>[#<Date: 2011-01-20 (4911163/2,0,2299161)>, #<Date: 2011-01-23 (4911169/2,0,2299161)>], 2=>[#<Date: 2011-02-01 (4911187/2,0,2299161)>, #<Date: 2011-02-15 (4911215/2,0,2299161)>], 3=>[#<Date: 2011-03-21 (4911283/2,0,2299161)>]}]]

这样我们就得到了二级分组。不再是一年中所有日期的数组,现在我们有哈希,其键是月份,值是给定月份的日期数组。

我们遇到的唯一问题是 map 返回一个数组而不是散列。这就是为什么我们用 Hash[]“包围”整个表达式,它从成对数组中生成散列,在我们的例子中是成对 [year, hash_of_dates_by_month]

抱歉,如果解释听起来令人困惑,我发现解释函数式表达式比命令式表达式更难,因为嵌套。 :(

关于ruby - 按月和年将 Ruby 日期数组分组为哈希,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5639921/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com