splice or split an array

P

Peter

Hello,
I try to split an array into a couple of arrays the same size.

This is my code and I think its very ugly ;-)

Does anoyone has a better idea?

@list =
("1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17"
,"18");

$pack =5;

$avg = $#list / $pack + 1;

for(1..$pack+1)
{
@newlist = splice(@list,0,$avg) if @list;

print "@newlist\n";
}
 
B

Brian McCauley

Peter said:
Hello,
I try to split an array into a couple of arrays the same size.

"A couple" is 2. I think you mean "an arbitrary number".

On course this is only possible if there are an exact multiple of that
number of elements in the original array. What do you want to happen if
this condition doesn't hold? I assume from your code you want the last
sublist to be short.
This is my code and I think its very ugly ;-)

I don't think it's _very_ ugly. It seems basically right - you use
splice(@list,0,$sublist_size).

I would scatter in a few 'my's in appropriate places.

I'd remove the the redundant 'if @list'. In general you should avoid
having an if that skips over a bit of code in the condition where the
bit of code wouldn't do anything at anyhow (unless there is a
significant performance issue).

I'd probably use a while rather than a for.

I'd use more mnemonic variables.

Does anoyone has a better idea?

@list =
("1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17"
,"18");

$pack =5;

$avg = $#list / $pack + 1;

for(1..$pack+1)
{
@newlist = splice(@list,0,$avg) if @list;

print "@newlist\n";
}

while( my @newlist = splice(@list,0,$sublist_size)) {
print "@newlist\n";
}

I can't really comment if your calculation is right since we don't know
your objectives.
 
J

John W. Krahn

Scott said:
Double quotes are neither necessary, nore desireable here.

my @list = qw(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18);

or

my @list = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18);

or

my @list = (1 .. 18);

Speaking of unnecessary, the parentheses are not required in the last example.
:)

my @list = 1 .. 18;


John
 
A

Anno Siegel

Peter said:
Hello,
I try to split an array into a couple of arrays the same size.

This is my code and I think its very ugly ;-)

Does anoyone has a better idea?

@list =
("1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17"
,"18");

$pack =5;

$avg = $#list / $pack + 1;

for(1..$pack+1)
{
@newlist = splice(@list,0,$avg) if @list;

print "@newlist\n";
}

Your loop runs one time too many. It will print the last partial
list twice. You seem to want $pack sublists, so the loop should
run over 1 .. $pack.

Equal sizes are, of course, only possible if $pack divides the length
of the original list. Your solution, like Brian's proposition, leaves
the last sublist short. If it matters, the sublist can be made more
equal than that:

my @list = 1 .. 18;
my $pack = 5;

my @sizes = ( int @list/$pack) x $pack;
$_ ++ for @sizes[ 0 .. @list % $pack - 1];
print "@$_\n" for map [ splice @list, 0, $_], @sizes;

This produces sublists whose sizes differ by at most one. The first
few (@list % $pack) are longer.

A similar result, but with the longer lists last, can be obtained
like this:

while ( @list ) {
my @newlist = splice @list, 0, @list/$pack--;
print "@newlist\n";
}

but that one is a little hard to verify. Will it ever divide by zero?
Also, it destroys not only @list, but also $pack.

Anno
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,733
Messages
2,569,440
Members
44,829
Latest member
PIXThurman

Latest Threads

Top