Select "n" elements from an array

Discussion in 'Perl Misc' started by usenet@DavidFilmer.com, Apr 25, 2006.

  1. Guest

    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.

    --
    http://DavidFilmer.com
    , Apr 25, 2006
    #1
    1. Advertising

  2. wrote:
    > 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.
    Brian McCauley, Apr 25, 2006
    #2
    1. Advertising

  3. Paul Lalli Guest

    wrote:
    > 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
    Paul Lalli, Apr 25, 2006
    #3
  4. Paul Lalli Guest

    Brian McCauley wrote:
    > 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
    Paul Lalli, Apr 25, 2006
    #4
  5. Guest

    Paul Lalli wrote:

    > 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).

    --
    http://DavidFilmer.com
    , Apr 25, 2006
    #5
  6. Anno Siegel Guest

    Brian McCauley <> wrote in comp.lang.perl.misc:
    >
    > wrote:
    > > 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
    --
    If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers.
    Anno Siegel, Apr 25, 2006
    #6
  7. Brad Baxter Guest

    wrote:
    > Paul Lalli wrote:
    >
    > > 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).
    >


    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,

    --
    Brad
    Brad Baxter, Apr 26, 2006
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. diffused
    Replies:
    9
    Views:
    723
    Oscar kind
    Aug 1, 2004
  2. P
    Replies:
    1
    Views:
    1,160
    Joe Kesselman
    Jul 7, 2006
  3. Glenn Ritz
    Replies:
    3
    Views:
    93
    Glenn Ritz
    Mar 20, 2010
  4. palmiere
    Replies:
    1
    Views:
    396
    Erwin Moller
    Feb 9, 2004
  5. SAN CAZIANO
    Replies:
    1
    Views:
    117
    Grant Wagner
    Nov 25, 2004
Loading...

Share This Page