给定一系列连续日期dates = (1..15).map { |num| Date.today + num }
如何删除星期日,但是为每个删除的星期日增加额外的一天来保留原始数组的长度?
这是我的尝试,导致“堆栈级太深”异常。
def remove_sundays(dates)
working_dates = dates.reject(&:sunday?)
size_diff = dates.size - working_dates.size
unless size_diff.zero?
last_day = working_dates.last
working_dates = working_dates + ((1..size_diff).map { |num| last_day + num })
remove_sundays(working_dates)
else
working_dates
end
end
答案 0 :(得分:2)
很难。
def remove_sundays(dates)
dates.each.with_index do |d, i|
if d.sunday?
dates[i..-1] = dates[i..-1].map(&:next_day)
end
end
end
答案 1 :(得分:1)
麻烦就是递归,这里:
remove_sundays(working_dates)
考虑如果上次工作日期是星期日会发生什么。该函数将删除该日期,然后看到它需要添加日期,然后添加一个日期,即星期日。这会导致递归永不终止。
但这可以在没有递归的情况下完成:
def remove_sundays(dates)
non_sundays = dates.reject(&:sunday?)
sunday_count = dates.size - non_sundays.size
date = dates.last + 1
sunday_count.times.map do
date += 1 if date.sunday?
non_sundays << date
date += 1
end
non_sundays
end
这两行与您的相同,但使用不同的变量名称:
non_sundays = dates.reject(&:sunday?)
sunday_count = dates.size - non_sundays.size
临时变量 date 将保留第二天添加。
date = dates.last + 1
现在添加日期到最后,我们删除的每个星期日一个,但不添加星期日。
sunday_count.times.map do
date += 1 if date.sunday?
non_sundays << date
date += 1
end
,最后,返回结果
non_sundays
如果日期将始终是连续的,如OP所述,则可以更简单地在没有任何星期日的情况下构建列表(而不是使用星期日构建列表,然后删除它们)。
def dates_without_sunday(date, count)
date -= 1
count.times.map do
date += 1
date += 1 if date.sunday?
date
end
end
dates = dates_without_sunday(Date.new(2014, 1, 16), 7)
p dates.map(&:wday)
# => [4, 5, 6, 1, 2, 3, 4]
答案 2 :(得分:1)
我改编了韦恩的回答:
def remove_sundays(dates)
date = dates.first - 1
dates.size.times.map do
date += 1
date += 1 if date.sunday?
date
end
end
答案 3 :(得分:0)
这是一种略有不同的方法,供您考虑。
我已将其概括为接受一系列wday,因此您可以更轻松地排除一周中任何日期的组合。位置中的“1”表示wday应包含在输出列表中。
def day_list(start_date = Date.today, day_count = 1, include_days = [1,1,1,1,1,1,1])
date_list = Array.new
date = start_date
wday_pattern = include_days
while date_list.size < day_count
date_list << date if wday_pattern[date.wday] == 1
date = date+1
end
date_list
end
在行动......
2.0.0dev :001 > require 'date'
=> true
2.0.0dev :002 >
2.0.0dev :003 > def day_list(start_date = Date.today, day_count = 1, include_days = [1,1,1,1,1,1,1])
2.0.0dev :004?> date_list = Array.new
2.0.0dev :005?> date = start_date
2.0.0dev :006?> wday_pattern = include_days
2.0.0dev :007?> while date_list.size < day_count
2.0.0dev :008?> date_list << date if wday_pattern[date.wday] == 1
2.0.0dev :009?> date = date+1
2.0.0dev :010?> end
2.0.0dev :011?> date_list
2.0.0dev :012?> end
=> nil
2.0.0dev :013 > day_list
=> [#<Date: 2014-01-16 ((2456674j,0s,0n),+0s,2299161j)>]
2.0.0dev :014 > day_list(Date.today,15,[1,1,1,1,1,1,0])
=> [#<Date: 2014-01-16 ((2456674j,0s,0n),+0s,2299161j)>, #<Date: 2014-01-17 ((2456675j,0s,0n),+0s,2299161j)>, #<Date: 2014-01-19 ((2456677j,0s,0n),+0s,2299161j)>, #<Date: 2014-01-20 ((2456678j,0s,0n),+0s,2299161j)>, #<Date: 2014-01-21 ((2456679j,0s,0n),+0s,2299161j)>, #<Date: 2014-01-22 ((2456680j,0s,0n),+0s,2299161j)>, #<Date: 2014-01-23 ((2456681j,0s,0n),+0s,2299161j)>, #<Date: 2014-01-24 ((2456682j,0s,0n),+0s,2299161j)>, #<Date: 2014-01-26 ((2456684j,0s,0n),+0s,2299161j)>, #<Date: 2014-01-27 ((2456685j,0s,0n),+0s,2299161j)>, #<Date: 2014-01-28 ((2456686j,0s,0n),+0s,2299161j)>, #<Date: 2014-01-29 ((2456687j,0s,0n),+0s,2299161j)>, #<Date: 2014-01-30 ((2456688j,0s,0n),+0s,2299161j)>, #<Date: 2014-01-31 ((2456689j,0s,0n),+0s,2299161j)>, #<Date: 2014-02-02 ((2456691j,0s,0n),+0s,2299161j)>]
2.0.0dev :015 > day_list(Date.today,8,[1,0,1,0,1,1,0])
=> [#<Date: 2014-01-16 ((2456674j,0s,0n),+0s,2299161j)>, #<Date: 2014-01-17 ((2456675j,0s,0n),+0s,2299161j)>, #<Date: 2014-01-19 ((2456677j,0s,0n),+0s,2299161j)>, #<Date: 2014-01-21 ((2456679j,0s,0n),+0s,2299161j)>, #<Date: 2014-01-23 ((2456681j,0s,0n),+0s,2299161j)>, #<Date: 2014-01-24 ((2456682j,0s,0n),+0s,2299161j)>, #<Date: 2014-01-26 ((2456684j,0s,0n),+0s,2299161j)>, #<Date: 2014-01-28 ((2456686j,0s,0n),+0s,2299161j)>]
2.0.0dev :016 >
答案 4 :(得分:0)
另一种方式:
require `date`
dates = (1..15).map { |num| Date.today + num }
# dates.day=>[17,18,19,20,21,22,23,24,25,26,27,28,29,30,31]
new_dates = dates.reject(&:sunday?)
# new_dates.map(&:day)=>[17,18, 20,21,22,23,24,25, 27,28,29,30,31]
next_date = new_dates.last + 1
loop do
new_dates << next_date unless next_date.sunday?
next_date += 1
break if new_dates.size == dates.size
end
# new_dates.map(&:day)=>[17,18, 20,21,22,23,24,25, 27,28,29,30,31,1, 3]
正如@Wayne所观察到的,直接生成无周日阵列更容易。这可以非常容易地完成:构建一个包含一堆连续日期的数组,去掉星期日并切掉所需的天数。要确定“束”的最小大小,请注意下一个count
天最多可以包含(count + 6)/7
个星期日。因此,
today = Date.today
count = 15
new_dates = 1.upto(count+(count+6)/7).map \
{ |i| today+i }.reject(&:sunday?).first(count)
# new_dates.map(&:day)=>[17,18, 20,21,22,23,24,25, 27,28,29,30,31,1, 3]