Select "n" elements from an array

U

usenet

This would not be difficult to code, but I suspect there's a good
module out there. However, my CPAN search skills have proven inadequate
to locate it.

I want to iterate over an array, selecting "n" elements at a time
(where "n" is an arbitrary number), something like:

foreach my @three_elements ( ?something?(1..10, 3) ) {
# @three_elements has three numbers in it
}

As the loop iterates, @three_elements would be:
(1,2,3)
(4,5,6)
(7,8,9)
(10,undef,undef)

It would not be difficult to code, but I have grasped the concept of
code reuse. Can someone kindly direct me to a module which does
something like this? I really think that such a module must exist - it
seems a common enough task.
 
B

Brian McCauley

This would not be difficult to code, but I suspect there's a good
module out there. However, my CPAN search skills have proven inadequate
to locate it.

I want to iterate over an array, selecting "n" elements at a time
(where "n" is an arbitrary number), something like:

foreach my @three_elements ( ?something?(1..10, 3) ) {
# @three_elements has three numbers in it
}

As the loop iterates, @three_elements would be:
(1,2,3)
(4,5,6)
(7,8,9)
(10,undef,undef)

Well, a module can't change the behaviour of for() or .. so it would be
more like

foreach my @$three_elements ( something(3 ,1..10) ) {
# @$three_elements has three numbers in it
}
It would not be difficult to code, but I have grasped the concept of
code reuse. Can someone kindly direct me to a module which does
something like this? I really think that such a module must exist - it
seems a common enough task.

It is a common task but usually it's OK to do it destructively. And if
it's not you can always make a copy.

my @stuff = (1..10);
while ( my @three_elements = splice @stuff, 0, 3 ) {

Note on the last interation @three_elements will have fewer elements
but this probably doesn't matter as $three_elements[1] will still be
undef.
 
P

Paul Lalli

This would not be difficult to code, but I suspect there's a good
module out there. However, my CPAN search skills have proven inadequate
to locate it.

I want to iterate over an array, selecting "n" elements at a time

Either List::Util or List::MoreUtils has just such a function, named
(not surprisingly) "natatime"

Paul Lalli
 
P

Paul Lalli

Brian said:
Well, a module can't change the behaviour of for() or ..

Really? I was under the impression that a module that implements
Source Filtering can pretty much change any language construct...

Paul Lalli
 
U

usenet

Paul said:
Either List::Util or List::MoreUtils has just such a function, named
(not surprisingly) "natatime"

It is List::MoreUtils - Thanks, Paul - that's EXACTLY what I was
looking for (and I should have guessed that Tassilo would have included
it in this Swiss Army Knife of list processing).
 
A

Anno Siegel

Brian McCauley said:
This would not be difficult to code, but I suspect there's a good
module out there. However, my CPAN search skills have proven inadequate
to locate it.

I want to iterate over an array, selecting "n" elements at a time
(where "n" is an arbitrary number), something like:

foreach my @three_elements ( ?something?(1..10, 3) ) {
# @three_elements has three numbers in it
}

As the loop iterates, @three_elements would be:
(1,2,3)
(4,5,6)
(7,8,9)
(10,undef,undef)
[...]

It is a common task but usually it's OK to do it destructively. And if
it's not you can always make a copy.

my @stuff = (1..10);
while ( my @three_elements = splice @stuff, 0, 3 ) {

Note on the last interation @three_elements will have fewer elements
but this probably doesn't matter as $three_elements[1] will still be
undef.

List::MoreUtils::natatime has been pointed out, so let's have some fun.

Non-destructive, and to specification with the final undef's:

for ( grep $_ % 3 == 0, 0 .. $#stuff ) {
my @three_elements = @stuff[ $_ .. $_ + 2];
# ...
}

Disadvantage: The parameter (3) appears twice, though it looks like 2
in one case.

Anno
 
B

Brad Baxter

It is List::MoreUtils - Thanks, Paul - that's EXACTLY what I was
looking for (and I should have guessed that Tassilo would have included
it in this Swiss Army Knife of list processing).

I'd be remiss if I didn't mention, ahem, *my* module: Array::Each.

use strict;
use warnings;

use Array::Each;

my @arr = ( 1 .. 10 );
my $are = Array::Each->new( \@arr );
$are->set_group( 3 );
$are->set_undef( 'undef' );

while( my ( $x, $y, $z ) = $are->each() ) {
print "( $x, $y, $z )\n";
}
__END__
( 1, 2, 3 )
( 4, 5, 6 )
( 7, 8, 9 )
( 10, undef, undef )

I have not benchmarked this against List::MoreUtils, but
I suspect natatime will blow it out of the water. :) When
I looked at the source for List::MoreUtils::each_array, I
said, "Dang, I wish I'd done it that way."

Perl6 will have each and zip, which will make some of
this moot anyway.

Cheers,
 

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,776
Messages
2,569,603
Members
45,190
Latest member
ClayE7480

Latest Threads

Top