Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

foreach loops

by richill (Monk)
on Oct 07, 2006 at 21:53 UTC ( #576909=perlquestion: print w/replies, xml ) Need Help??
richill has asked for the wisdom of the Perl Monks concerning the following question:

I'm almost embarassed to ask this because Im sure the answer is no, but is it possible to have a foreach loop loop through and array and return 2 values of the array in the same call.

I'll try to explain it better,

@names = ('rita', 'sue','bob', 'daisy') foreach $name (@names){ print "$name xxxxx \n"; }
the xxxx would be some code that makes this function return
rita sue sue bob bob daisy daisy

If not, what is the best way of doing this? Im leaning towards using a forloop and the array in a scalar context.

Replies are listed 'Best First'.
Re: foreach loops
by Arunbear (Parson) on Oct 07, 2006 at 22:30 UTC
    Here is one way:
    use strict; my @names = ('rita', 'sue','bob', 'daisy'); $, = ' '; $\ = "\n"; foreach (0 .. $#names) { print @names[$_, $_+1]; }
    Output:
    rita sue sue bob bob daisy daisy
      If warnings are switched on you will get an 'Use of uninitialized value ...' message once you get to the last time around the loop as print tries to access one more element than is in the array. This stops the warning.

      use strict; use warnings; my @names = qw{rita sue bob daisy}; $, = q{ }; $\ = qq{\n}; foreach (0 .. $#names) { print $_ == $#names ? $names[$_] : @names[$_, $_ + 1]; }

      Cheers,

      JohnGG

        Thank you everyone. I think I've strayed into the relms of perl magic. What are these operators called? I'd like to find out more about them

        $,

        $\

Re: foreach loops
by Corion (Pope) on Oct 07, 2006 at 21:58 UTC

    foreach doesn't do that, but List::MoreUtils has the natatime (n-at-a-time) function, which does what you want:

    #!/opt/perl/bin/perl -w use strict; use List::MoreUtils qw(natatime); my @names = qw( a b c d e f ); my $it = natatime( 2, @names ); while (my @items = $it->()) { print "@items\n"; };

    Update: My answer is wrong - you want to process two items in the list, but reprocess items - Arunbear's solution below is what you want then. I didn't read your wanted output closely enough, sorry.

Re: foreach loops
by shenme (Priest) on Oct 07, 2006 at 21:57 UTC
    Check out List::MoreUtils natatime() as one way to do it.
Re: foreach loops
by zentara (Archbishop) on Oct 08, 2006 at 13:00 UTC
    Just for the sake of fun, if you switch to a while loop
    #!/usr/bin/perl use warnings; use strict; my @names = ('rita', 'sue','bob', 'daisy'); while (@names){ my $name1 = shift @names; my $name2 = shift @names; if( defined $name2){ print "$name1 $name2\n"; unshift @names, $name2; }else{ print "$name1\n";} }

    Output:

    rita sue sue bob bob daisy daisy

    I'm not really a human, but I play one on earth. Cogito ergo sum a bum
Re: foreach loops
by dokkeldepper (Friar) on Oct 08, 2006 at 10:38 UTC

    A very elegant and general solution: use Algorithm::Combinatorics qw/.../;

    For example:

    use Algorithm::Combinatorics qw/combinations/; @names = ('rita', 'sue','bob', 'daisy'); my $r=combinations(\@names,2); while(my $res=$r->next){ print "@$res\n"; }

    There are several other combinatorical functions to replace all these foreach loops...

Re: foreach loops
by pbeckingham (Parson) on Oct 08, 2006 at 13:19 UTC

    I think a C-style for loop would be appropriate here:

    my @names = ('rita', 'sue','bob', 'daisy'); for (my $i = 0; $i < @names; ++$i) { print $names[$i], ' ', ($names[$i+1] || ''), "\n"; }
    Output:
    rita sue sue bob bob daisy daisy



    pbeckingham - typist, perishable vertebrate.
Re: foreach loops
by jwkrahn (Monsignor) on Oct 09, 2006 at 00:15 UTC
    Just to add One More Way To Do It:
    $ perl -we' my $names = join " ", ( "rita", "sue", "bob", "daisy" ); while ( $names =~ /(\S+)(?=\s*(\S*))/g ) { print "$1\t$2\n"; } ' rita sue sue bob bob daisy daisy

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://576909]
Approved by Corion
help
Chatterbox?
[Corion]: If you cram your slides with that much information, they might work in an "offline" situation but not very well for a live presentation IMO
[ambrus]: Corion: in that case I also ask the people who rent the conference rooms to tell conference organizers about the available tech.
[Corion]: ambrus: No, you're misunderstanding. If you place content too far on the left/right/top/ bottom, people might not see it because the view is obstructed ;)(
[Corion]: In Amsterdam, the screen went down to the bottom of the stage (60cm above ground) and the seating was on the ground, meaning that the rows in the back couldn't see the bottom of slides.
[Corion]: There also were some columns that meant that maybe you couldn't see the left/right edge of a slide.
[ambrus]: Corion: Sure. I've had a course in a 50 seat lecture hall that has two fucking columns in the middle.
[Corion]: Talking about it, the top should be fairly visible in the situations I've experienced at least. The top is uncomfortable for people in the first three rows, but that's life ;)
[ambrus]: The pillars are there because this is in the 6th floor of building R of BME, which is an attic that was built in after the original building, which is also why the elevator doesn't go that high and the windows are tiny.
[Corion]: ambrus: Hehe ;) Yeah - such real life stuff is far more inconveniencing than wasting display area due to screen ratio problems :)
[ambrus]: Corion: yes, it's a bit tricky. you can try to adjust the slides live to cover only a part of the screen, but it's still hard.

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (12)
As of 2017-09-26 10:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    During the recent solar eclipse, I:









    Results (293 votes). Check out past polls.

    Notices?