为什么 `later` 方法会导致 `Date` 范围无限大?
Why doe `later` method lead to infinite range in `Date` range?
在 Julia 中,您可以 generate a date range by month 像这样:
julia> dr = Date(2014,1,29):Dates.Month(1):Date(2014,07,29)
Date("2014-01-29"):Month(1):Date("2014-07-29")
julia> collect(dr)
7-element Array{Date,1}:
2014-01-29
2014-02-28
2014-03-29
2014-04-29
2014-05-29
2014-06-29
2014-07-29
Date(2014,1,29)
是开始日期,Dates.Month(1)
是步骤,Date(2014,07,29)
是结束日期。
Raku 有一个方法 later,但在自定义生成器中使用时,它会导致无限范围:
lazy my @dates = Date.new('2014-01-29'), Date.new('2014-02-28'), { $^a.later(:1month) } ... Date.new('2014-07-29')
如果我在 ... 运算符的右侧使用 * >= Date.new('2014-07-29')
而不是 Date.new('2014-07-29')
,它会起作用:
lazy my @a = Date.new('2014-01-29'), Date.new('2014-02-28'), { $^a.later(:1month) } ... * >= Date.new('2014-07-29')
2014-01-29
2014-02-28
2014-03-28
2014-04-28
2014-05-28
2014-06-28
2014-07-28
2014-08-28
为什么 { $^a.later(:1month) } ... Date.new('2014-07-29')
中的自定义生成器 { $^a.later(:1month) }
不会在 2014-07-29
处停止并导致无限范围?
正如 JJMerelo 在评论中指出的那样,...
运算符的工作方式是继续根据 left-hand-arguments 生成元素,直到(根据智能匹配)准确达到 right-hand-argument .
例如,如果我们做一个10的倍数的序列,
my @tens = 0, 10, 20 ... 95;
say @tens[10]; # 100
say @tens[11]; # 110
这是因为 @tens
的元素实际上不是 95。要确定一个元素是否是最后一个元素,使用智能匹配运算符 (~~
)。智能匹配 DateTime
与另一个 Datetime
returns 如果两者代表相同时间(由于时区等原因可能是不同的标称时间),则为真。
对于序列,DateTime
因 .later
和 .earlier
不可交换而变得更加复杂,因此 $date.later(:1month).later(:1month)
不能保证给出相同的结果作为 $date.later(:2month)
.
* ≥ DateTime.new(…)
不同的原因是 Callable
对象的智能匹配(从技术上讲,它是等效于 anon sub $dt { $dt ≥ DateTime.new(…) }
的任何代码将左侧参数传递给可调用对象。如果您不能 100% 确定序列将通过达到精确值而终止,最好使用 whatever code 方法来确保值最终匹配。
嗯 - 对于任何尝试这个的孩子来说,“我的意思”有一些陷阱......例如当我尝试这个时
lazy my @b = Date.new('2014-01-31'), Date.new('2014-02-28'), { $^a.later(:1month) } ... * >= Date.new('2014-07-29')
我明白了...
#(2014-01-31 2014-02-28 2014-03-28 ...)
但也许我想要每个月的最后一天,如果 2014 年是闰年,等等,等等
所以如果你想要最后一天(或最后一天-1),那么也有这个方便的方法...
say Date.new('2015-11-24').last-date-in-month;
在 Julia 中,您可以 generate a date range by month 像这样:
julia> dr = Date(2014,1,29):Dates.Month(1):Date(2014,07,29)
Date("2014-01-29"):Month(1):Date("2014-07-29")
julia> collect(dr)
7-element Array{Date,1}:
2014-01-29
2014-02-28
2014-03-29
2014-04-29
2014-05-29
2014-06-29
2014-07-29
Date(2014,1,29)
是开始日期,Dates.Month(1)
是步骤,Date(2014,07,29)
是结束日期。
Raku 有一个方法 later,但在自定义生成器中使用时,它会导致无限范围:
lazy my @dates = Date.new('2014-01-29'), Date.new('2014-02-28'), { $^a.later(:1month) } ... Date.new('2014-07-29')
如果我在 ... 运算符的右侧使用 * >= Date.new('2014-07-29')
而不是 Date.new('2014-07-29')
,它会起作用:
lazy my @a = Date.new('2014-01-29'), Date.new('2014-02-28'), { $^a.later(:1month) } ... * >= Date.new('2014-07-29')
2014-01-29
2014-02-28
2014-03-28
2014-04-28
2014-05-28
2014-06-28
2014-07-28
2014-08-28
为什么 { $^a.later(:1month) } ... Date.new('2014-07-29')
中的自定义生成器 { $^a.later(:1month) }
不会在 2014-07-29
处停止并导致无限范围?
正如 JJMerelo 在评论中指出的那样,...
运算符的工作方式是继续根据 left-hand-arguments 生成元素,直到(根据智能匹配)准确达到 right-hand-argument .
例如,如果我们做一个10的倍数的序列,
my @tens = 0, 10, 20 ... 95;
say @tens[10]; # 100
say @tens[11]; # 110
这是因为 @tens
的元素实际上不是 95。要确定一个元素是否是最后一个元素,使用智能匹配运算符 (~~
)。智能匹配 DateTime
与另一个 Datetime
returns 如果两者代表相同时间(由于时区等原因可能是不同的标称时间),则为真。
对于序列,DateTime
因 .later
和 .earlier
不可交换而变得更加复杂,因此 $date.later(:1month).later(:1month)
不能保证给出相同的结果作为 $date.later(:2month)
.
* ≥ DateTime.new(…)
不同的原因是 Callable
对象的智能匹配(从技术上讲,它是等效于 anon sub $dt { $dt ≥ DateTime.new(…) }
的任何代码将左侧参数传递给可调用对象。如果您不能 100% 确定序列将通过达到精确值而终止,最好使用 whatever code 方法来确保值最终匹配。
嗯 - 对于任何尝试这个的孩子来说,“我的意思”有一些陷阱......例如当我尝试这个时
lazy my @b = Date.new('2014-01-31'), Date.new('2014-02-28'), { $^a.later(:1month) } ... * >= Date.new('2014-07-29')
我明白了...
#(2014-01-31 2014-02-28 2014-03-28 ...)
但也许我想要每个月的最后一天,如果 2014 年是闰年,等等,等等
所以如果你想要最后一天(或最后一天-1),那么也有这个方便的方法...
say Date.new('2015-11-24').last-date-in-month;