web-dev-qa-db-ja.com

日付範囲を逆にループするにはどうすればよいですか?

逆にループできるようにしたい日付範囲があります。次のように、これをどのように達成しますか。標準のRange演算子が正しく機能していないようです。

>> sd = Date.parse('2010-03-01')
=> Mon, 01 Mar 2010
>> ed = Date.parse('2010-03-05')
=> Fri, 05 Mar 2010
>> (sd..ed).to_a
=> [Mon, 01 Mar 2010, Tue, 02 Mar 2010, Wed, 03 Mar 2010, Thu, 04 Mar 2010, Fri, 05 Mar     2010]
>> (ed..sd).to_a
=> []

ご覧のとおり、範囲演算子は最初から最後まで正しく機能しますが、最後から最初までは機能しません。

31
Russ Bradberry

Upto/downtoを試してください:

irb(main):003:0> sd = Date.parse('2010-03-01')
=> #<Date: 4910513/2,0,2299161>
irb(main):004:0> ed = Date.parse('2010-03-15')
=> #<Date: 4910541/2,0,2299161>
irb(main):005:0> sd.upto(ed) { |date| puts date }
2010-03-01
2010-03-02
2010-03-03
2010-03-04
2010-03-05
2010-03-06
2010-03-07
2010-03-08
2010-03-09
2010-03-10
2010-03-11
2010-03-12
2010-03-13
2010-03-14
2010-03-15
=> #<Date: 4910513/2,0,2299161>
irb(main):006:0> ed.downto(sd) { |date| puts date }
2010-03-15
2010-03-14
2010-03-13
2010-03-12
2010-03-11
2010-03-10
2010-03-09
2010-03-08
2010-03-07
2010-03-06
2010-03-05
2010-03-04
2010-03-03
2010-03-02
2010-03-01
=> #<Date: 4910541/2,0,2299161>
62
Joseph Weissman

私は通常、結果の配列を逆にします。

Ruby-1.8.7-p72 > sd = Date.parse('2010-03-01')
 => Mon, 01 Mar 2010 
Ruby-1.8.7-p72 > ed = Date.parse('2010-03-05')
 => Fri, 05 Mar 2010 
Ruby-1.8.7-p72 > (sd..ed).to_a
 => [Mon, 01 Mar 2010, Tue, 02 Mar 2010, Wed, 03 Mar 2010, Thu, 04 Mar 2010, Fri, 05 Mar 2010] 
Ruby-1.8.7-p72 > (sd..ed).to_a.reverse
 => [Fri, 05 Mar 2010, Thu, 04 Mar 2010, Wed, 03 Mar 2010, Tue, 02 Mar 2010, Mon, 01 Mar 2010] 

開始日が終了日の前か後かわからないときに正しいことをするためには、次のようなものが必要だと思います。

def date_range(sd, ed)
  sd < ed ? (sd..ed).to_a : (ed..sd).to_a.reverse
end

これはどちらの方法でもあなたに正しいことを与えるでしょう:

Ruby-1.8.7-p72 > sd = Date.parse('2010-03-01')
 => Mon, 01 Mar 2010 
Ruby-1.8.7-p72 > ed = Date.parse('2010-03-05')
 => Fri, 05 Mar 2010 
Ruby-1.8.7-p72 > date_range(sd, ed)
 => [Mon, 01 Mar 2010, Tue, 02 Mar 2010, Wed, 03 Mar 2010, Thu, 04 Mar 2010, Fri, 05 Mar 2010] 
Ruby-1.8.7-p72 > date_range(ed, sd)
 => [Fri, 05 Mar 2010, Thu, 04 Mar 2010, Wed, 03 Mar 2010, Tue, 02 Mar 2010, Mon, 01 Mar 2010] 
6