为什么我的一些范围疯了?

Chr*_*oms 3 perl6

我尝试将范围(例如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;
}
Run Code Online (Sandbox Code Playgroud)

这打印:

1 2 3 4 5 6 7 8 9
1
11 10 21 20
Run Code Online (Sandbox Code Playgroud)

而不是预期的:

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
Run Code Online (Sandbox Code Playgroud)

(在发布这个问题之前我已经弄明白了,所以我在下面回答.如果你想详细说明,请随意添加你自己的答案).

Eli*_*sen 9

问题确实是.split回归Str而不是Int原始答案所解决的问题.但是,我宁愿像这样实现我的"get_range_for":

sub get_range_for($string) {
    Range.new( |$string.split("-")>>.Int )
}
Run Code Online (Sandbox Code Playgroud)

这将返回一个Range对象而不是一个Array.但是对于迭代(这是你最有可能使用它),这不会有任何区别.此外,对于更大的范围,"get_range_for"的其他实现可能会占用大量内存,因为它可以将其Range转化为Array.这对于"3-10"来说并不重要,但它会用于"1-10000000".

请注意,此实现用于>>.Int对从其返回的所有值调用Int方法.split,然后将它们作为单独的参数滑动|Range.new..split如果返回1值(如果它不能拆分)或超过2个值(如果字符串中出现多个连字符),那么这也会爆炸.


Chr*_*oms 7

结果split是a Str,因此您不小心创建了一系列字符串而不是一系列整数.尝试转换$start$stopInt创建范围之前:

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;
}
Run Code Online (Sandbox Code Playgroud)

给你你期望的东西:

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
Run Code Online (Sandbox Code Playgroud)

  • 这种方法很好,但是对于较大的范围可能会占用大量的内存,因为你正在激活范围.我会把它写成:`sub get_range_for($ string){Range.new(| $ string.split(" - ")>>.Int)}`.这将返回Range对象,如果您愿意,可以稍后迭代*或*存储在数组中.注意,这使用`>>.Int`对`.split`返回的所有值调用`Int`方法,然后将它们作为单独的参数滑动,使用`|`转换为`Range.new`. (2认同)