use*_*275 1 arrays perl split reference
我试图将数值数组拆分成更小的数组,这样每个较小的数组都不能包含任何不同的数字.
示例:(2,2,2,2,2,9,3,3,3,3)应将数组拆分为三个数组(2,2,2,2,2),(9)并且(3,3,3,3).
这是我尝试过的:
my @arr = (2,2,2,2,2,9,3,3,3,3);
my @result = ();
my $last = -1;
my @newarr = ();
for my $i (0 .. $#arr){
if ( ($i>0 && $arr[$i] != $last) || $i == $#arr ){
push @result, \@newarr;
@newarr = ();
}
$last = $arr[$i];
push @newarr, $arr[$i];
}
Run Code Online (Sandbox Code Playgroud)
首先,这段代码没有给我想要的结果.我觉得我的错误是,当我推提及@newarr到@result,但后来我重新初始化@newarr.
其次,有没有更优雅的方法来做到这一点?我看了看功能split和splice,但也想不出好的解决方案.
List :: MoreUtils具有" part"功能:
use Data::Dumper;
use feature 'state';
use List::MoreUtils 'part';
my @array = ( 2,2,2,2,2, 9, 3,3,3,3 );
my @part = part {
state $prev;
state $i = -1;
$i++ if !defined($prev) || $_ ne $prev;
$prev = $_;
$i
} @array;
print Dumper @part;
Run Code Online (Sandbox Code Playgroud)
使用'part',代码块返回的值指示顶级数组索引,其中当前值将被推送到匿名数组中. $prev从未定义开始,因此输入中的第一个元素将触发$i递增0,因此所有'2'将最终进入@{$part[0]}.只要@array中的元素与$ prev不匹配,索引就会递增,后续元素最终会出现@{$part[1]}.每次检测到更改时,都会开始新的分组.
更新:
如果这段代码可能被多次使用,那么"状态"变量将在调用之间保持其值.在这种情况下,状态比它的价值更麻烦,人们应该在子例程中使用词法:
use Data::Dumper;
use List::MoreUtils 'part';
my @array = ( 2,2,2,2,2, 9, 3,3,3,3 );
my @part = partition(@array);
print Dumper \@part;
sub partition {
my( $prev, $i ) = ( undef, -1 );
return part {
$i++ if ! defined($prev) || $_ ne $prev;
$prev = $_;
$i;
} @_;
}
Run Code Online (Sandbox Code Playgroud)