【发布时间】:2020-01-22 17:06:46
【问题描述】:
我如何在位置列表中很好地/惯用地拆分字符串?
我有什么:
.say for split-at( "0019ABX26002", (3, 4, 8) );
sub split-at( $s, @positions )
{
my $done = 0;
gather
{
for @positions -> $p
{
take $s.substr($done, $p - $done );
$done = $p;
}
take $s.substr( $done, * );
}
}
这是合理的。不过,我对此缺乏语言支持感到困惑。如果“拆分”是一件事,为什么“拆分”也不行?我认为这应该是一个核心操作。我应该会写
.say for "0019ABX26002".split( :at(3, 4, 8) );
或者我忽略了什么?
编辑:我们目前所拥有的一个小基准
O------------O---------O------------O--------O-------O-------O
| | Rate | array-push | holli | raiph | simon |
O============O=========O============O========O=======O=======O
| array-push | 15907/s | -- | -59% | -100% | -91% |
| holli | 9858/s | 142% | -- | -100% | -79% |
| raiph | 72.8/s | 50185% | 20720% | -- | 4335% |
| simon | 2901/s | 1034% | 369% | -98% | -- |
O------------O---------O------------O--------O-------O-------O
代码:
use Bench;
my $s = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbccccddddddddddddddddddddddddddddddddddddefggggggggggggggggggg";
my @p = 29, 65, 69, 105, 106, 107;
Bench.new.cmpthese(1000, {
holli => sub { my @ = holli($s, @p); },
simon => sub { my @ = simon($s, @p); },
raiph => sub { my @ = raiph($s, @p); },
array-push => sub { my @ = array-push($s, @p); },
});
#say user($s, @p);
sub simon($str, *@idxs ) {
my @rotors = @idxs.map( { state $l = 0; my $o = $_ - $l; $l = $_; $o } );
$str.comb("").rotor( |@rotors,* ).map(*.join(""));
}
sub raiph($s, @p) {
$s.split( / <?{$/.pos == any(@p)}> / )
}
sub holli( $s, @positions )
{
my $done = 0;
gather
{
for @positions -> $p
{
take $s.substr($done, $p - $done );
$done = $p;
}
take $s.substr( $done, * );
}
}
sub array-push( $s, @positions )
{
my $done = 0;
my @result;
for @positions -> $p
{
@result.push: $s.substr($done, $p - $done );
$done = $p;
}
@result.push: $s.substr( $done, * );
@result;
}
【问题讨论】:
-
所以你期待这个:
("001", "9", "ABX2", "6002")? -
在这种情况下,这将是输出 yes。
-
如果您正在寻找原始速度,那么创建一个显式返回数组会更快一些:收集/获取大约为 15k,而 Array/push 大约为 19k,但这是假设每个item 是最终需要的。
-
哦,哇,我没想到。我测量了我的初始代码和 eqiv 之间接近 100% 的速度差异。带有显式数组和推送的代码。知道为什么聚集这么慢吗?
-
鉴于这个问题,我添加了一个模块:String::Fields。它的界面略有不同,但我认为它在其他情况下也更灵活,更有用。
标签: raku