为什么我的一些范围是疯狂的?
Why are some of my ranges insane?
我尝试将范围的常见字符串描述(例如 1-9
)解析为实际范围(例如 1 .. 9
),但在包含两位数字时经常会得到奇怪的结果。例如,1-10
导致单个值 1
而不是十个值的列表,并且 11-20
给了我四个值 (11 10 21 20
),其中一半不是在预期的数值范围内:
put get_range_for('1-9');
put get_range_for('1-10');
put get_range_for('11-20');
sub get_range_for ( $string ) {
my ($start, $stop) = $string.split('-');
my @values = ($start .. $stop).flat;
return @values;
}
这会打印:
1 2 3 4 5 6 7 8 9
1
11 10 21 20
而不是预期的:
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
(我在发布这个问题之前就想通了,所以我在下面回答了。如果您想详细说明,请随时添加您自己的答案)。
split
的结果是 Str
,因此您不小心创建了一个字符串范围而不是整数范围。在创建范围之前尝试将 $start
和 $stop
转换为 Int
:
put get_range_for('1-9');
put get_range_for('1-10');
put get_range_for('11-20');
sub get_range_for ( $string ) {
my ($start, $stop) = $string.split('-');
my @values = ($start.Int .. $stop.Int).flat; # Simply added .Int here
return @values;
}
满足您的期望:
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
问题确实是 .split
returns Str
而不是 Int
,原来的答案解决了。但是,我宁愿像这样实现我的 "get_range_for":
sub get_range_for($string) {
Range.new( |$string.split("-")>>.Int )
}
这将 return 一个 Range
对象而不是 Array
。但是对于迭代(这是您最有可能使用它的目的),这不会有任何区别。此外,对于更大的范围,"get_range_for" 的其他实现可能会占用大量内存,因为它将 Range
激活为 Array
。这对“3-10”来说并不重要,但对“1-10000000”来说却很重要。
请注意,此实现使用 >>.Int
对从 .split
编辑的所有值 return 调用 Int 方法,然后使用 |
将它们作为单独的参数传递至 Range.new
。如果 .split
return 1 个值(如果它不能拆分)或超过 2 个值(如果字符串中出现多个连字符),这也会炸弹。
我尝试将范围的常见字符串描述(例如 1-9
)解析为实际范围(例如 1 .. 9
),但在包含两位数字时经常会得到奇怪的结果。例如,1-10
导致单个值 1
而不是十个值的列表,并且 11-20
给了我四个值 (11 10 21 20
),其中一半不是在预期的数值范围内:
put get_range_for('1-9');
put get_range_for('1-10');
put get_range_for('11-20');
sub get_range_for ( $string ) {
my ($start, $stop) = $string.split('-');
my @values = ($start .. $stop).flat;
return @values;
}
这会打印:
1 2 3 4 5 6 7 8 9
1
11 10 21 20
而不是预期的:
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
(我在发布这个问题之前就想通了,所以我在下面回答了。如果您想详细说明,请随时添加您自己的答案)。
split
的结果是 Str
,因此您不小心创建了一个字符串范围而不是整数范围。在创建范围之前尝试将 $start
和 $stop
转换为 Int
:
put get_range_for('1-9');
put get_range_for('1-10');
put get_range_for('11-20');
sub get_range_for ( $string ) {
my ($start, $stop) = $string.split('-');
my @values = ($start.Int .. $stop.Int).flat; # Simply added .Int here
return @values;
}
满足您的期望:
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
问题确实是 .split
returns Str
而不是 Int
,原来的答案解决了。但是,我宁愿像这样实现我的 "get_range_for":
sub get_range_for($string) {
Range.new( |$string.split("-")>>.Int )
}
这将 return 一个 Range
对象而不是 Array
。但是对于迭代(这是您最有可能使用它的目的),这不会有任何区别。此外,对于更大的范围,"get_range_for" 的其他实现可能会占用大量内存,因为它将 Range
激活为 Array
。这对“3-10”来说并不重要,但对“1-10000000”来说却很重要。
请注意,此实现使用 >>.Int
对从 .split
编辑的所有值 return 调用 Int 方法,然后使用 |
将它们作为单独的参数传递至 Range.new
。如果 .split
return 1 个值(如果它不能拆分)或超过 2 个值(如果字符串中出现多个连字符),这也会炸弹。