【问题标题】:How can I loop through each of the days of a given week in Ruby?如何在 Ruby 中循环遍历给定一周的每一天?
【发布时间】:2010-05-18 18:45:05
【问题描述】:

我使用以下方法定义星期一和星期五:

@monday = Date.today.at_beginning_of_week

@friday = 5.days.since(@monday)

但实际上,对于任何一天,我都需要循环遍历星期一、星期二、星期三,然后获取该日期并将输出放入列中。

<th>Monday</th>
<th>Tuesday</th>
etcetera

例如,给定的行将是:

<tr><td>method_with_arg(monday)</td><td>method_with_arg(tuesday)</td><td>method_with_arg(wednesday)</td></tr>

这里的 value 是一个接受 args 日期的方法。

最干净的方法是什么?

谢谢。

【问题讨论】:

    标签: ruby-on-rails ruby loops date


    【解决方案1】:
    def dates_week(d)
      (d.beginning_of_week...d.beginning_of_week+5).map{|a|
        "<td>#{a.strftime('%F')}</td>"
      }.join
    end
    
    dates_week Date.today
    #=> "<td>2010-05-17</td><td>2010-05-18</td><td>2010-05-19</td><td>2010-05-20</td><td>2010-05-21</td>"
    

    除了a.strftime,您还可以调用任何其他方法接收日期并返回字符串,例如mails_sent_on(a) 等。您还可以使用yield a 在那里使用块传递您的日期相关逻辑:

    def dates_week(d)
      (d.beginning_of_week...d.beginning_of_week+5).map{|a|
        yield a
      }.join
    end
    
    dates_week(Date.today) { |d|
      "<td>#{mails_sent_on(d)}</td>"
    }
    

    或者,将字符串排除在dates_week 方法之外:

    def dates_week(d)
      (d.beginning_of_week...d.beginning_of_week+5).map{|a|
        yield a
      }
    end
    
    dates_week(Date.today) { |d|
      mails_sent_on(d)
    }.join(', ')
    

    或任何你需要的形式。

    【讨论】:

    • 我需要将日期的实际值传递给另一个方法以输出其他行的值,例如发送的电子邮件、拨打的电话、添加的联系人等等......我该如何设置输出成为我可以作为参数插入的变量?
    • 除了我对 non-DRY-ness 的担忧之外,我认为您需要在 d.beginning_of_week+5 周围加上一个括号(去过那里,做过)
    • @Angela:我不确定我是否理解你。 @Andrew:至少在 Ruby 1.9 中不需要括号。也试过你的例子,不管有没有括号都一样。
    • 我想我的意思是我需要将实际日期(我认为)而不是字符串传递给表格每一行的另一种方法(例如,显示当天发送的所有电子邮件) ....格式是 sent_emails(a) 吗?
    【解决方案2】:

    我只使用普通的旧 Ruby 对象,但我认为如果你想保持 DRY,你需要将工作日的逻辑与你使用工作日的逻辑分开。

    def dates_week(d)
      d.beginning_of_week...(d.beginning_of_week+5)
    end
    
    dates_week(Date.today).map {|a|
      "<td>#{a.strftime('%F')}</td>"
    }.join
    

    【讨论】:

      【解决方案3】:

      我什至会比 Andrew 走得更远,让它挡住:

      def dates_week(d, delim)
        "<tr>" + (d.beginning_of_week...(d.beginning_of_week+5)).map do |day|
          "<#{delim}> #{yield(day)} </#{delim}>"
        end.join + "</tr>"
      end
      
      dates_week(Date.today, "th") {|d| d.strftime("%A")} # => <tr><th>Monday</th><th>Tuesday</th>...
      dates_week(Date.today, "td") {|d| some_function(d)} #first row
      

      【讨论】:

      • 好吧,就这样吧——但现在我找不到通过传入参数发送的所有电子邮件,因为这些电子邮件使用日期时间戳......:\
      • 你应该能够找到()他们这样一天
      【解决方案4】:

      我能想到的最简单的解决方案是:

      first_day = Date.today.at_beginning_of_week
      days = 7.times.map {|x| first_day + x.days }
      
      days.each do |day|
           puts "<td>" + func(day) + "</td>"
      end
      

      这应该可以解决问题

      【讨论】:

      • 这看起来很简单......但所有这些都需要在视图中进行,或者在 dates_week() 中进行
      • 我会定义一个辅助方法。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-20
      • 2019-06-12
      • 1970-01-01
      • 2014-06-29
      • 2019-12-13
      • 2015-04-14
      相关资源
      最近更新 更多