Why are some of my ranges insane?

心已入冬 提交于 2020-01-14 14:31:11

问题


I tried parsing a common string depiction of ranges (e.g. 1-9) into actual ranges (e.g. 1 .. 9), but often got weird results when including two digit numbers. For example, 1-10 results in the single value 1 instead of a list of ten values and 11-20 gave me four values (11 10 21 20), half of which aren't even in the expected numerical range:

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;
}

This prints:

1 2 3 4 5 6 7 8 9
1
11 10 21 20

Instead of the expected:

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

(I figured this out before posting this question, so I have answered below. Feel free to add your own answer if you'd like to elaborate).


回答1:


The problem is indeed that .split returns Str rather than Int, which the original answer solves. However, I would rather implement my "get_range_for" like this:

sub get_range_for($string) {
    Range.new( |$string.split("-")>>.Int )
}

This would return a Range object rather than an Array. But for iteration (which is what you most likely would use this for), this wouldn't make any difference. Also, for larger ranges the other implementation of "get_range_for" could potentially eat a lot of memory because it vivifies the Range into an Array. This doesn't matter much for "3-10", but it would for "1-10000000".

Note that this implementation uses >>.Int to call the Int method on all values returned from the .split, and then slips them as separate parameters with | to Range.new. This will then also bomb should the .split return 1 value (if it couldn't split) or more than 2 values (if multiple hyphens occurred in the string).




回答2:


The result of split is a Str, so you are accidentally creating a range of strings instead of a range of integers. Try converting $start and $stop to Int before creating the range:

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;
}

Giving you what you expect:

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


来源:https://stackoverflow.com/questions/44835476/why-are-some-of-my-ranges-insane

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!