T
Tore Aursand
Hi there!
I need to split an array into "even" parts, so that each resulting array
contains the same number of elements.
Think of it as splitting a list of many names into multiple columns, and
you want x numbers of names in each column so that each column gets filled
up even-wise.
The problem arise, of course, when you have 10 elements and want to split
those into 3 columns. That should be listed like this:
+-------+-------+-------+
| Col 1 | Col 2 | Col 3 |
+-------+-------+-------+
| 1 | 5 | 9 |
| 2 | 6 | 10 |
| 3 | 7 | |
| 4 | 8 | |
+-------+-------+-------+
So far I've come up with this solution:
sub split_array {
my $array = shift; # Array reference
my $parts = shift; # Number of columns to split into
## Make sure $parts is set (default = 2), and that it isn't
## larger than the number of elements in $array
$parts ||= 2;
$parts = @$array if ( $parts > @$array );
## Split
my @split = (); # Will contain the splitted data
my $slice = POSIX::ceil( @$array / $parts ); # Size of each part
for ( 1 .. $parts ) {
if ( $_ == $parts ) {
push( @split, $array );
}
else {
push( @split, splice(@$array, 0, $slice) );
}
}
## Return
return \@split;
}
This code is doubtly the most efficient (I'm always looking for
efficient, yet readable, ways to do things), and I haven't run that many
tests on it either. Any comments on it?
I need to split an array into "even" parts, so that each resulting array
contains the same number of elements.
Think of it as splitting a list of many names into multiple columns, and
you want x numbers of names in each column so that each column gets filled
up even-wise.
The problem arise, of course, when you have 10 elements and want to split
those into 3 columns. That should be listed like this:
+-------+-------+-------+
| Col 1 | Col 2 | Col 3 |
+-------+-------+-------+
| 1 | 5 | 9 |
| 2 | 6 | 10 |
| 3 | 7 | |
| 4 | 8 | |
+-------+-------+-------+
So far I've come up with this solution:
sub split_array {
my $array = shift; # Array reference
my $parts = shift; # Number of columns to split into
## Make sure $parts is set (default = 2), and that it isn't
## larger than the number of elements in $array
$parts ||= 2;
$parts = @$array if ( $parts > @$array );
## Split
my @split = (); # Will contain the splitted data
my $slice = POSIX::ceil( @$array / $parts ); # Size of each part
for ( 1 .. $parts ) {
if ( $_ == $parts ) {
push( @split, $array );
}
else {
push( @split, splice(@$array, 0, $slice) );
}
}
## Return
return \@split;
}
This code is doubtly the most efficient (I'm always looking for
efficient, yet readable, ways to do things), and I haven't run that many
tests on it either. Any comments on it?