Pulling pairs of values from an array

Discussion in 'Perl Misc' started by RedGrittyBrick, Dec 17, 2010.

  1. Consider

    #!/usr/bin/perl
    use strict;
    use warnings;

    while(<DATA>) {
    my($t1,$t2,$value);
    ($t1,$t2)=qw(A P); $value = $1 if /^$t1.*$t2=(.)/;
    ($t1,$t2)=qw(B Q); $value = $1 if /^$t1.*$t2=(.)/;
    ($t1,$t2)=qw(C R); $value = $1 if /^$t1.*$t2=(.)/;
    print "$value\n";
    }

    __DATA__
    A P=1 Q=2 R=3
    B P=8 Q=2 R=7
    C Q=2 P=1 R=3

    I'd like to replace the repetition with an elegant loop over pairs of
    $t1,$t2 values stored in an array (or other structure) like one of

    my @pairs = qw (A,P B,Q C,R);
    my @pairs = qw (A P B Q C R);

    I've not had much success with a brief attempt at combining `while`,
    `split` and `unshift`.

    What concise, elegant solution am I missing?


    (Also posted to stackoverflow.com, let me know if you object. I'll post
    a combined summary of answers to both fora as penance)

    --
    RGB
     
    RedGrittyBrick, Dec 17, 2010
    #1
    1. Advertising

  2. On 17/12/2010 11:59, RedGrittyBrick wrote:
    > Consider
    >
    > #!/usr/bin/perl
    > use strict;
    > use warnings;
    >
    > while(<DATA>) {
    > my($t1,$t2,$value);
    > ($t1,$t2)=qw(A P); $value = $1 if /^$t1.*$t2=(.)/;
    > ($t1,$t2)=qw(B Q); $value = $1 if /^$t1.*$t2=(.)/;
    > ($t1,$t2)=qw(C R); $value = $1 if /^$t1.*$t2=(.)/;
    > print "$value\n";
    > }
    >
    > __DATA__
    > A P=1 Q=2 R=3
    > B P=8 Q=2 R=7
    > C Q=2 P=1 R=3
    >
    > I'd like to replace the repetition with an elegant loop over pairs of
    > $t1,$t2 values stored in an array (or other structure) like one of
    >
    > my @pairs = qw (A,P B,Q C,R);
    > my @pairs = qw (A P B Q C R);
    >
    > I've not had much success with a brief attempt at combining `while`,
    > `split` and `unshift`.
    >
    > What concise, elegant solution am I missing?
    >
    >
    > (Also posted to stackoverflow.com, let me know if you object. I'll post
    > a combined summary of answers to both fora as penance)
    >


    In
    <http://stackoverflow.com/questions/4470189/perl-pulling-pairs-of-values-from-an-array/4470453#4470453>
    Sorpigal suggested

    #!/usr/bin/perl
    use strict;
    use warnings;

    my %pairs = qw/A P B Q C R/;

    foreach my $data (<DATA>) {
    while(my($t1, $t2) = each(%pairs)){
    $data =~ /^$t1.*$t2=(.)/ && print "$1\n";
    }
    }

    Which I like. (YMMV)

    --
    RGB
     
    RedGrittyBrick, Dec 17, 2010
    #2
    1. Advertising

  3. On 17/12/2010 14:01, Tad McClellan wrote:
    > RedGrittyBrick<> wrote:
    >> Consider
    >>
    >> #!/usr/bin/perl
    >> use strict;
    >> use warnings;
    >>
    >> while(<DATA>) {
    >> my($t1,$t2,$value);
    >> ($t1,$t2)=qw(A P); $value = $1 if /^$t1.*$t2=(.)/;
    >> ($t1,$t2)=qw(B Q); $value = $1 if /^$t1.*$t2=(.)/;
    >> ($t1,$t2)=qw(C R); $value = $1 if /^$t1.*$t2=(.)/;
    >> print "$value\n";
    >> }
    >>
    >> __DATA__
    >> A P=1 Q=2 R=3
    >> B P=8 Q=2 R=7
    >> C Q=2 P=1 R=3

    >
    >
    > That data looks like an HoH to me...
    >
    >
    >> I'd like to replace the repetition with an elegant loop over pairs of
    >> $t1,$t2 values stored in an array (or other structure) like one of
    >>
    >> my @pairs = qw (A,P B,Q C,R);
    >> my @pairs = qw (A P B Q C R);

    >
    >
    > my %pairs = qw/A P B Q C R/;
    >
    > while (<DATA>) {
    > my($type, %values) = split /[\s=]/;
    > print "$values{$pairs{$type}}\n";
    > }
    >
    >


    Thanks. The inventiveness of clpm contributors is a great source of
    inspiration.

    A Sinan Ünür posted four solutions with some commentary in
    <http://stackoverflow.com/questions/4470189/perl-pulling-pairs-of-values-from-an-array/4470720#4470720>.
    I'm not sure I can summarise it adequately so I'll just post the URL
    here rather than paste it all in verbatim.

    --
    RGB
     
    RedGrittyBrick, Dec 17, 2010
    #3
  4. RedGrittyBrick

    Guest

    On Fri, 17 Dec 2010 11:59:38 +0000, RedGrittyBrick <> wrote:

    >Consider
    >
    > #!/usr/bin/perl
    > use strict;
    > use warnings;
    >
    > while(<DATA>) {
    > my($t1,$t2,$value);
    > ($t1,$t2)=qw(A P); $value = $1 if /^$t1.*$t2=(.)/;
    > ($t1,$t2)=qw(B Q); $value = $1 if /^$t1.*$t2=(.)/;
    > ($t1,$t2)=qw(C R); $value = $1 if /^$t1.*$t2=(.)/;
    > print "$value\n";
    > }
    >
    > __DATA__
    > A P=1 Q=2 R=3
    > B P=8 Q=2 R=7
    > C Q=2 P=1 R=3
    >
    >I'd like to replace the repetition with an elegant loop over pairs of
    >$t1,$t2 values stored in an array (or other structure) like one of
    >
    > my @pairs = qw (A,P B,Q C,R);
    > my @pairs = qw (A P B Q C R);
    >
    >I've not had much success with a brief attempt at combining `while`,
    >`split` and `unshift`.
    >
    >What concise, elegant solution am I missing?
    >
    >
    >(Also posted to stackoverflow.com, let me know if you object. I'll post
    >a combined summary of answers to both fora as penance)


    You don't have to check all the pairs.
    You can just get the value with a single if statement
    per line of data. Its must faster this way.

    Either of these will work (and there is validation so warnings
    are not emitted) :

    /^(\S+)/g && exists $pairs{$1} && /\G.*$pairs{$1}=(\S+)/
    /^(\S+)(??{exists $pairs{$1} ? ".*$pairs{$1}=" : "(*FAIL)"})(\S+)/

    -sln

    -----------------------------
    use strict;
    use warnings;

    my %pairs = qw/A P B Q C R/;

    while ( <DATA> )
    {
    if (/^(\S+)/g && exists $pairs{$1} && /\G.*$pairs{$1}=(\S+)/) {
    print $1,"\n";
    }
    }
    __DATA__

    A P=1 Q=2 R=3
    B P=8 Q=2 R=7
    C Q=2 P=1 R=3


    Optional, uses extended regex (??{..}):
    while ( <DATA> )
    {
    if (/^(\S+)(??{exists $pairs{$1} ? ".*$pairs{$1}=" : "(*FAIL)"})(\S+)/) {
    print $2,"\n";
    }
    }
     
    , Dec 17, 2010
    #4
    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. Ben Davies
    Replies:
    3
    Views:
    364
    Erik Max Francis
    Jan 14, 2004
  2. Replies:
    6
    Views:
    528
    bugbear
    Nov 17, 2006
  3. puzzlecracker

    generating random array of pairs

    puzzlecracker, Jul 29, 2008, in forum: Java
    Replies:
    10
    Views:
    615
  4. Jon Hawkins
    Replies:
    7
    Views:
    86
    Stefan Rusterholz
    Aug 6, 2007
  5. Michael Furmaniuk

    Pulling values from strings

    Michael Furmaniuk, Apr 14, 2009, in forum: Ruby
    Replies:
    4
    Views:
    173
    Michael Furmaniuk
    Apr 15, 2009
Loading...

Share This Page