Perl - 将数组拆分为更小的均匀分布的数组

3
我该如何将一个任意大小的 Perl 数组分成数量不确定的较小数组,使得每个较小数组中的元素数量尽可能均等?原始数组不能被破坏。

2
“尽可能均匀”是什么意思?一个大小为11的数组可以分成5,6或4,4,3或2,2,2,2,2,1。 - user485498
这里可能会有用:https://dev59.com/YnI_5IYBdhLWcg3wMf5_。至于我的上述观点,你必须决定如何分割数组,即4,4,3、4,3,4或3,4,4。这种方式有关系吗? - user485498
数组的大小在该示例中始终是3的倍数,而不是任意大小的数组。数组被分割的方式并不重要。 - user774234
natatime使用splice函数,这会破坏原始数组。因此,它在保留原始数组的条件方面失败了。 - user774234
我最初想到了natatime,但是除了手动完成整个过程外,我无法想出更好的方法。 - Dallaylaen
显示剩余3条评论
4个回答

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. 

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;

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;

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;
    };

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接