Ruby 从日期数组中删除星期日,但根据删除星期日进行调整

Ruby 从日期数组中删除星期日,但根据删除星期日进行调整,ruby,Ruby,给定一个连续日期数组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.zer

给定一个连续日期数组
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

问题在于递归,这里:

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
临时变量日期将保留要添加的第二天

  date = dates.last + 1
现在在末尾添加日期,我们删除的每个星期天都有一个日期,但不要添加任何星期天

  sunday_count.times.map do  
    date += 1 if date.sunday?
    non_sundays << date
    date += 1
  end
可供替代的 如果日期总是连续的,如OP所述,那么简单地构建没有任何星期天的列表可能更简单(而不是构建一个包含星期天的列表,然后删除它们)


问题在于递归,这里:

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
临时变量日期将保留要添加的第二天

  date = dates.last + 1
现在在末尾添加日期,我们删除的每个星期天都有一个日期,但不要添加任何星期天

  sunday_count.times.map do  
    date += 1 if date.sunday?
    non_sundays << date
    date += 1
  end
可供替代的 如果日期总是连续的,如OP所述,那么简单地构建没有任何星期天的列表可能更简单(而不是构建一个包含星期天的列表,然后删除它们)

硬的

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
硬的

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

这里有一个稍微不同的方法,供您考虑

我将其推广为接受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
def day_列表(开始日期=date.today,day_count=1,include_days=[1,1,1,1,1,1])
date\u list=Array.new
日期=开始日期
wday\u模式=包括天
而date\u list.size正确
2.0.0开发:002>
2.0.0dev:003>定义日期列表(开始日期=日期。今天,日期计数=1,包括日期=[1,1,1,1,1,1])
2.0.0dev:004?>date\u list=Array.new
2.0.0开发:005?>日期=开始日期
2.0.0dev:006?>wday\u模式=包含\u天
2.0.0dev:007?>而date\u list.size日期\列表日期=日期+1
2.0.0开发:010?>结束
2.0.0开发:011?>日期列表
2.0.0开发:012?>结束
=>零
2.0.0dev:013>每日列表
=> [#] 
2.0.0dev:014>日期列表(日期:今天,15,[1,1,1,1,1,0])
=> [#, #, #, #, #, #, #, #, #, #, #, #, #, #, #] 
2.0.0dev:015>日期列表(日期:今天,8,[1,0,1,0,1,0])
=> [#, #, #, #, #, #, #, #] 
2.0.0开发:016>

这里有一个稍微不同的方法供您考虑

我将其推广为接受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
def day_列表(开始日期=date.today,day_count=1,include_days=[1,1,1,1,1,1])
date\u list=Array.new
日期=开始日期
wday\u模式=包括天
而date\u list.size正确
2.0.0开发:002>
2.0.0dev:003>定义日期列表(开始日期=日期。今天,日期计数=1,包括日期=[1,1,1,1,1,1])
2.0.0dev:004?>date\u list=Array.new
2.0.0开发:005?>日期=开始日期
2.0.0dev:006?>wday\u模式=包含\u天
2.0.0dev:007?>而date\u list.size日期\列表日期=日期+1
2.0.0开发:010?>结束
2.0.0开发:011?>日期列表
2.0.0开发:012?>结束
=>零
2.0.0dev:013>每日列表
=> [#] 
2.0.0dev:014>日期列表(日期:今天,15,[1,1,1,1,1,0])
=> [#, #, #, #, #, #, #, #, #, #, #, #, #, #, #] 
2.0.0dev:015>日期列表(日期:今天,8,[1,0,1,0,1,0])
=> [#, #, #, #, #, #, #, #] 
2.0.0开发:016>

我改编了韦恩的答案:

def remove_sundays(dates)
  date = dates.first - 1
  dates.size.times.map do
    date += 1
    date += 1 if date.sunday?
    date
  end
end

我修改了韦恩的回答:

def remove_sundays(dates)
  date = dates.first - 1
  dates.size.times.map do
    date += 1
    date += 1 if date.sunday?
    date
  end
end
另一种方式:

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]
另一种方式:

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]

星期天?在Rails 1.9.3中,因此如果它曾经是Rails扩展,那么它已经被移植到了base Ruby。日期是否总是连续的?@WayneConrad很高兴知道,询问更新以删除Rails引用。是的,它们将是连续的几天,我也更新了问题以反映这一点。在这种情况下,创建没有任何星期日的列表可能更简单。请参阅我刚才在回答中添加的“备选方案”部分。日期#周日?在Rails 1.9.3中,因此如果它曾经是Rails扩展,那么它已经被移植到了base Ruby。日期是否总是连续的?@WayneConrad很高兴知道,询问更新以删除Rails引用。是的,它们将是连续的几天,我也更新了问题以反映这一点。在这种情况下,创建没有任何星期日的列表可能更简单。请参阅我刚刚添加到我的答案中的“备选方案”一节。这个解是O(n^2),而我的解是O(n),但这很美。除了非常大的列表,我更喜欢这个解决方案。伊万,新的解决方案是O(n),但一点也不漂亮。它还假设日期是连续的。OP的示例输入数据是连续的,但我们不知道它总是如此闪亮。这个解是O(n^2),而我的解是O(n),但这很美。除了非常大的列表,我更喜欢这个解决方案。伊万,新的解决方案是O(n),但一点也不漂亮。它还假设日期是连续的。OP的示例输入数据是连续的,但我们不知道它总是连续的。我采用了替代解决方案。