在特定位置拆分数字数组

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.

其次,有没有更优雅的方法来做到这一点?我看了看功能splitsplice,但也想不出好的解决方案.

Dav*_*idO 5

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)

  • 如果这个代码多次运行,你不希望那里有状态变量...... (2认同)