How can I slice a string like Python does in Perl 6?

人走茶凉 提交于 2019-12-05 19:36:06

How to slice a string

Strings (represented as class Str) are seen as single values and not positional data structures in Perl 6, and thus can't be indexed/sliced with the built-in [ ] array indexing operator.

As you already suggested, comb or substr is the way to go:

my $solo = "A quick brown fox jumps over the lazy dog";

dd $solo.comb[3..4].join;   # "ui"
dd $solo.comb[3..^5].join;  # "ui"

dd $solo.substr(3, 2);      # "ui"
dd $solo.substr(3..4);      # "ui"
dd $solo.substr(3..^5);     # "ui"

If you want to modify the slice, use substr-rw:

$solo.substr-rw(2..6) = "slow";
dd $solo;  # "A slow brown fox jumps over the lazy dog"

How to make operator [ ] work directly on strings

If you really wanted to, you could compose a role into your string that adds method AT-POS, which would make the [ ] operator work on it:

my $solo = "A quick brown fox jumps over the lazy dog" but role {
    method AT-POS ($i) { self.substr($i, 1) }
}

dd $solo[3..5]; ("u", "i", "c")

However, this returns slices as a list, because that's what the [ ] operator does by default. To make it return a concatenated string, you'd have to re-implement [ ] for type Str:

multi postcircumfix:<[ ]>(Str $string, Int:D $index) {
    $string.substr($index, 1)
}
multi postcircumfix:<[ ]>(Str $string, Range:D $slice) {
    $string.substr($slice)
}
multi postcircumfix:<[ ]>(Str $string, Iterable:D \slice) {
    slice.map({ $string.substr($_, 1) }).join
}

my $solo = "A quick brown fox jumps over the lazy dog";

dd $solo[3];     # "u"
dd $solo[3..4];  # "ui"
dd $solo[3, 5];  # "uc"

You could extend the [ ] multi-candidates added here to handle all the other magic that the operator provides for lists, like:

  • from-the-end indices, e.g. $solo[*-1]
  • truncating slices, e.g. $solo[3..*]
  • adverbs, e.g. $solo[3..5]:kv
  • assignment, e.g. $solo[2..6] = "slow"

But it would take a lot of effort to get all of that right.

Also, keep in mind that overriding built-in operators to do things they weren't supposed to do, will confuse other Perl 6 programmers who will have to review or work with your code in the future.

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