如何将任意大小的Perl数组拆分为可变数量的较小数组,每个较小数组中的元素数量均匀分布?不得销毁原始数组。
答案 0 :(得分:8)
脱离我的头顶:
use strict;
use warnings;
use Data::Dumper; # for debugging only
print Dumper(distribute(7, [1..30]));
# takes number+arrayref, returns ref to array of arrays
sub distribute {
my ($n, $array) = @_;
my @parts;
my $i = 0;
foreach my $elem (@$array) {
push @{ $parts[$i++ % $n] }, $elem;
};
return \@parts;
};
这可以保证@parts中的元素数量只能相差一个。还有其他解决方案可以预先计算数字并使用拼接:
push @parts, [ @$array[$offset..$offset+$chunk] ];
$offset += chunk;
# alter $chunk if needed.
答案 1 :(得分:5)
这是使用List :: MoreUtils的版本:
use strict;
use warnings;
use List::MoreUtils qw(part);
use Data::Dumper;
my @array = 1..9;
my $partitions = 3;
my $i = 0;
print Dumper part {$partitions * $i++ / @array} @array;
答案 2 :(得分:1)
如果你不在乎每个阵列中出现什么:
use strict;
use warnings;
use List::MoreUtils qw(part);
use Data::Dumper;
my $i = 0;
my $numParts = 2;
my @part = part { $i++ % $numParts } 1 .. 30;
print Dumper @part;
答案 3 :(得分:1)
@ Dallaylaen的答案并不常用,因为你无法将数组传递给Perl中的子程序。您不必传入数组(或Dallaylaen在其示例中所做的列表),而是必须传入对数组的引用:
my @arrayIn = (1..30);
my @arrayOfArrays = distribute(7, \@arrayIn);
sub distribute {
my ($n, $array) = @_;
my @parts;
my $i = 0;
foreach my $elem (@$array) {
push @{ $parts[$i++ % $n] }, $elem;
};
return @parts;
};