How can I partition a Perl array into equal sized chunks?

后端 未结 9 1460
眼角桃花
眼角桃花 2020-12-15 08:01

I have a fixed-sized array where the size of the array is always in factor of 3.

my @array = (\'foo\', \'bar\', \'qux\', \'foo1\', \'bar\', \'qux2\', 3, 4, 5         


        
相关标签:
9条回答
  • 2020-12-15 08:23

    Try this:

    $VAR = [map $_ % 3 == 0 ? ([ $array[$_], $array[$_ + 1], $array[$_ + 2] ]) 
                            : (),
                0..$#array];
    
    0 讨论(0)
  • 2020-12-15 08:24

    Another generic solution, non-destructive to the original array:

    use Data::Dumper;
    
    sub partition {
        my ($arr, $N) = @_; 
    
        my @res;
        my $i = 0;
    
        while ($i + $N-1 <= $#$arr) {
            push @res, [@$arr[$i .. $i+$N-1]];
            $i += $N; 
        }   
    
        if ($i <= $#$arr) {
            push @res, [@$arr[$i .. $#$arr]];
        }   
        return \@res;
    }
    
    print Dumper partition(
        ['foo', 'bar', 'qux', 'foo1', 'bar', 'qux2', 3, 4, 5], 
        3   
    );
    

    The output:

    $VAR1 = [
              [
                'foo',
                'bar',
                'qux'
              ],
              [
                'foo1',
                'bar',
                'qux2'
              ],
              [
                3,
                4,
                5
              ]
            ];
    
    0 讨论(0)
  • 2020-12-15 08:30

    Or this:

    my $VAR;
    while( my @list = splice( @array, 0, 3 ) ) {
        push @$VAR, \@list;
    }
    
    0 讨论(0)
  • 2020-12-15 08:30

    Use the spart function from the List::NSect package on CPAN.

        perl -e '
        use List::NSect qw{spart};
        use Data::Dumper qw{Dumper};
        my @array = ("foo", "bar", "qux", "foo1", "bar", "qux2", 3, 4, 5);
        my $var = spart(3, @array);
        print Dumper $var;
        '
    
        $VAR1 = [
              [
                'foo',
                'bar',
                'qux'
              ],
              [
                'foo1',
                'bar',
                'qux2'
              ],
              [
                3,
                4,
                5
              ]
            ];
    
    0 讨论(0)
  • 2020-12-15 08:35

    Another answer (a variation on Tore's, using splice but avoiding the while loop in favor of more Perl-y map)

    my $result = [ map { [splice(@array, 0, 3)] } (1 .. (scalar(@array) + 2) % 3) ];
    
    0 讨论(0)
  • 2020-12-15 08:38
    my @VAR;
    push @VAR, [ splice @array, 0, 3 ] while @array;
    

    or you could use natatime from List::MoreUtils

    use List::MoreUtils qw(natatime);
    
    my @VAR;
    {
      my $iter = natatime 3, @array;
      while( my @tmp = $iter->() ){
        push @VAR, \@tmp;
      }
    }
    
    0 讨论(0)
提交回复
热议问题