[英]Shift values that satisfy some rule
我有一個數字數組,希望刪除數組開頭的所有非正數(即零或負數)。 這是我所擁有的:
shiftlbl:
$shift = shift @ary;
if (0 >= $shift) {goto shiftlbl;}
else {unshift @ary, $shift;}
有沒有一種方法可以更好(更快)地工作,或者可以近似地同樣地工作,但是卻更易讀懂?
無需使用任何模塊,您可以使用
shift @ary while @ary && $ary[0] <= 0;
不僅可讀性強; 它也快得多。
或者,您可以嘗試僅更改一次數組,如果要刪除的部分很長,則可以加快處理過程:
use List::Util qw{ first };
my $i = first { $ary[$_] > 0 } 0 .. $#ary;
splice @ary, 0, $i;
對於-1000 .. 200
,我得到了
Rate old new splice
old 2782/s -- -62% -69%
new 7371/s 165% -- -17%
splice 8886/s 219% 21% --
這是完整的代碼:
#!/usr/bin/perl
use warnings;
use strict;
use List::Util qw{ first };
use Test::More;
use Benchmark qw{ cmpthese };
sub old {
my @ary = @_;
shiftlbl:
my $shift = shift @ary;
if (0 >= $shift) {goto shiftlbl;}
else {unshift @ary, $shift;}
return @ary
}
sub new {
my @ary = @_;
shift @ary while @ary && $ary[0] <= 0;
return @ary
}
sub sp {
my @ary = @_;
my $i = first { $ary[$_] > 0 } 0 .. $#ary;
splice @ary, 0, $i;
return @ary
}
my @ar = (-1000 .. 200);
is_deeply([old(@ar)], [new(@ar)], 'old - new');
is_deeply([old(@ar)], [sp(@ar)], 'old - splice');
cmpthese(-5,
{
old => sub { old(@ar) },
new => sub { new(@ar) },
splice => sub { sp(@ar) },
# Also tried with similar results:
# old => 'old( -1000 .. 200)',
# new => 'new( -1000 .. 200)',
# splice => 'sp( -1000 .. 200)',
});
done_testing();
您可以使用after_incl
從列表:: MoreUtils :
use strict;
use warnings;
use Data::Dump;
use List::MoreUtils qw(after_incl);
my @numbers = (-2, -17, 2, -1, 5, 0);
my @starts_positive = after_incl { $_ > 0 } @numbers;
dd \@starts_positive;
[2, -1, 5, 0]
after_incl
獲取一個列表,對其應用一個塊,直到該塊返回true,然后從該點返回原始列表的末尾的值列表。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.