digitalmars.D.learn - Date range iteration
- Jordan Wilson (16/16) Mar 11 2018 I wanted to iterate through a date range, so I initially tried:
- Jonathan M Davis (23/38) Mar 11 2018 Maybe iota should be made to work, but as present, it basically wants al...
- Jordan Wilson (5/13) Mar 12 2018 Yes I agree, a for loop for simple iteration is fine, but I'm
I wanted to iterate through a date range, so I initially tried: iota(Date(2016,1,1),Date(2018,1,1),dur!"days"(1)); That wouldn't compile, which is fair enough I guess. So I tried a for loop: for (auto i = Date(2016,1,1); i < Date(2018,1,1); i+=dur!"days"(1)){} That seemed to work fine, but I remember reading "for loops are bad" somewhere. So I looked for a range type mechanism, and I think it's this: foreach (i; Interval!Date (Date(2016,1,1),Date(2018,1,1)).fwdRange ( (a) { return a+dur!"days"(1); })){} My question is if the third way is the proper way of stepping through a period of time? It just seems quite complicated to me. Thanks, Jordan
Mar 11 2018
On Monday, March 12, 2018 02:11:49 Jordan Wilson via Digitalmars-d-learn wrote:I wanted to iterate through a date range, so I initially tried: iota(Date(2016,1,1),Date(2018,1,1),dur!"days"(1)); That wouldn't compile, which is fair enough I guess.Maybe iota should be made to work, but as present, it basically wants all three of the types it's given to be the same or implicitly convertible to a single type. It can't handle the step being a completely different type.So I tried a for loop: for (auto i = Date(2016,1,1); i < Date(2018,1,1); i+=dur!"days"(1)){} That seemed to work fine, but I remember reading "for loops are bad" somewhere.for loops are just fine - especially if you're just going to loop through all the values and do something to them - but if you have a range, it's a lot more flexible.So I looked for a range type mechanism, and I think it's this: foreach (i; Interval!Date (Date(2016,1,1),Date(2018,1,1)).fwdRange ( (a) { return a+dur!"days"(1); })){} My question is if the third way is the proper way of stepping through a period of time? It just seems quite complicated to me.Well, honestly, the range support in std.datetime isn't very good. The core problem that overcomplicates it is that the Interval needs to know which direction you want to iterate in, and then the helper functions tend to need to know it too in order to work properly. Also, the time point type being used also tends to get duplicated a fair bit. So, you end up with annoyingly repetitive code. The helper function intended for this use case is https://dlang.org/phobos/std_datetime_interval.html#everyDuration So, you'd get something more like auto interval = Interval!Date(Date(2016, 1, 1), Date(2018, 1, 1)); auto range = interval.fwdRange(everyDuration!Date(days(1))); But if you're just going to use the range in a foreach loop, then you might as well just use a for loop. All of this extra machinery only really starts being valuable when you start feeding the ranges into range-based functions. For a simple loop, it's overkill. - Jonathan M Davis
Mar 11 2018
On Monday, 12 March 2018 at 02:49:34 UTC, Jonathan M Davis wrote:On Monday, March 12, 2018 02:11:49 Jordan Wilson via Digitalmars-d-learn wrote:Yes I agree, a for loop for simple iteration is fine, but I'm sure there are cases where a date range would be quite useful, so the everyDuration tip is great, thanks! Jordan[...]Maybe iota should be made to work, but as present, it basically wants all three of the types it's given to be the same or implicitly convertible to a single type. It can't handle the step being a completely different type. [...]
Mar 12 2018