从一系列日期,
arr = ["2020-01-05", "2020-01-06", "2020-01-07", "2020-01-08",
"2020-01-09", "2020-02-12", "2020-02-13", "2020-02-14"]
我们如何对它们进行分组,例如输出变为如下:
["Jan 5th - Jan 9th", "Feb 12th - Feb 14th"]
属于该范围内的日期应按上述方式分组。众所周知,arr
的所有元素的年份都相同,因此可以忽略不计。
我想说你可以用to_date
转换它们,按它们的month
分组,并按它们的minmax
映射它们:
arr
.map(&:to_date)
.group_by(&:month)
.map do |_, dates|
dates.minmax.map { |date| date.to_s(:long_ordinal) }.join(' - ')
end
# ["January 5th, 2020 - January 9th, 2020", "February 12th, 2020 - February 14th, 2020"]
to_s(:long_ordinal)
是获取格式化字符串。
arr = ["2020-01-05", "2020-01-06", "2020-01-07", "2020-01-08", "2020-01-09", "2020-02-12", "2020-02-13", "2020-02-14"]
arr
.map { |d| Date.parse(d) }
.group_by { |d| d.month }
.sort
.map do |d|
dt = d.last
min = dt.min
max = dt.max
"#{min.strftime('%b')} #{min.day.ordinalize} - #{max.strftime('%b')} #{dt.max.day.ordinalize}"
end
您可以按如下方式执行此操作。
require 'date'
ORDINAL = { 1=>"st", 2=>"nd", 3=>"rd" }.tap { |h| h.default = "th" }
arr.group_by { |s| s[5,2] }.
map do |mon, arr|
mon_name = Date::ABBR_MONTHNAMES[mon.to_i]
first_day, last_day = arr.map { |s| s[-2,2].to_i }.minmax.
map { |d| "%d%s" % [d, ORDINAL[d%10]] }
"%s %s - % s %s" % [mon_name, first_day, mon_name, last_day]
end
#=> ["Jan 5th - Jan 9th", "Feb 12nd - Feb 14th"]
步骤如下:
ORDINAL = { 1=>"st", 2=>"nd", 3=>"rd" }.tap { |h| h.default = "th" }
ORDINAL[0] #=> "th"
ORDINAL[1] #=> "st"
ORDINAL[2] #=> "nd"
ORDINAL[3] #=> "rd"
ORDINAL[4] #=> "th"
...
h = arr.group_by { |s| s[5,2] }
#=> {"01"=>["2020-01-05", "2020-01-06", "2020-01-07",
# "2020-01-08", "2020-01-09"],
# "02"=>["2020-02-12", "2020-02-13", "2020-02-14"]}
enum = h.to_a.each
#=> #<Enumerator:...
mon, arr = enum.next
#=> ["01", ["2020-01-05", "2020-01-06", "2020-01-07",
# "2020-01-08", "2020-01-09"]]
mon
#=> "01"
arr
#=> ["2020-01-05", "2020-01-06", "2020-01-07", "2020-01-08",
# "2020-01-09"]
mon_name = Date::ABBR_MONTHNAMES[mon.to_i]
#=> "Jan"
a = arr.map { |s| s[-2,2].to_i }
#=> [5, 6, 7, 8, 9]
b = a.minmax
#=> [5, 9]
first_day, last_day = b.map { |d| "%d%s" % [d, ORDINAL[d%10]] }
#=> ["5th", "9th"]
"%s %s - % s %s" % [mon_name, first_day, mon_name, last_day]
#=> "Jan 5th - Jan 9th"
mon, arr = enum.next
#=> ["02", ["2020-02-12", "2020-02-13", "2020-02-14"]]
其余步骤类似。
没有其他答案可以处理同一月中的单天和连续几天的多次运行:
dates = ["2020-01-05", "2020-01-06", "2020-01-07",
"2020-01-09",
"2020-01-12", "2020-01-13", "2020-01-14",
"2020-02-12", "2020-02-13", "2020-02-14"].map(&Date.method(:parse))
def ordinalize(num)
ordinals = { 1 => :st, 2 => :nd, 3 => :rd, 4 => :th }
ord_num = (11..13).cover?(num.abs % 100) ? 4 : num.abs
"#{num}#{ordinals[ord_num]}"
end
grouped = dates.sort.chunk_while { |a, b| a + 1 == b }.map(&:minmax).map(&:uniq)
grouped.map do |group|
group.map { |date| date.strftime("%b #{ordinalize(date.day)}") }.join(" - ")
end
# => ["Jan 5th - Jan 7th", "Jan 9th", "Jan 12th - Jan 14th", "Feb 12th - Feb 14th"]
迷你奖金,碰巧不依赖于ActiveSupport