2010-05-14 17 views
27

Ho un intervallo di date che mi piacerebbe essere in grado di scorrere al contrario. Dare il seguente, come potrei realizzare questo, l'operatore standard Range non sembra funzionare correttamente.Come faccio a passare da un intervallo di date all'indietro?

>> 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 
=> [] 

come si può vedere, l'operatore di intervallo funziona correttamente dall'inizio alla fine, ma non dalla fine all'inizio.

risposta

58

Prova fino a/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> 
+0

Se sei pigro puoi anche usare semplicemente .collect.reverse che funziona altrettanto bene nella maggior parte delle circostanze. – tadman

+1

eccetto che poi deve prima costruire l'intero array e poi invertirlo. in alto e in basso sono gli enumeratori. –

5

Io di solito basta invertire la matrice risultante:

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] 

Credo che, per fargli fare la cosa giusta, quando non si sa se l'inizio data sarà prima o dopo la data di fine, vorresti qualcosa sulla falsariga di:

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

che darà o la cosa giusta in ogni caso:

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] 
Problemi correlati