elegant way of getting last REAL value of an array

Discussion in 'Perl Misc' started by ccc31807, Jul 19, 2012.

  1. ccc31807

    ccc31807 Guest

    I have three values that may or may not contain values, call them
    $grad1, $grad2, and $grad3. The values they may contain are dates,
    like this: 04/12.

    My current code munges them like this:
    my $grad = ""; # if there are no dates
    $grad = $grad1 if $grad1 =~ /\d\d/;
    $grad = $grad2 if $grad2 =~ /\d\d/;
    $grad = $grad3 if $grad3 =~ /\d\d/;

    What I might like to do is this:
    my @grad = ($grad1, $grad2, $grad3);
    my $grad = ??? #either the last value of @grad that matches /\d\d/ or
    "" if none does

    Maybe it's a mental block, but I can't figure out how to do this.

    Ideas?

    Thanks, CC.
    ccc31807, Jul 19, 2012
    #1
    1. Advertising

  2. Am 19.07.2012 18:11, schrieb ccc31807:
    > I have three values that may or may not contain values, call them
    > $grad1, $grad2, and $grad3. The values they may contain are dates,
    > like this: 04/12.
    >
    > What I might like to do is this:
    > my @grad = ($grad1, $grad2, $grad3);
    > my $grad = ??? #either the last value of @grad that matches /\d\d/ or
    > "" if none does
    >
    > Maybe it's a mental block, but I can't figure out how to do this.


    Using the List::Util module:

    use List::Util qw(first);
    my @dates=qw(abc 01/02 02/03 de);
    say first {/\d\d/} reverse @g'

    - Wolf
    Wolf Behrenhoff, Jul 19, 2012
    #2
    1. Advertising

  3. ccc31807

    ccc31807 Guest

    On Jul 19, 12:35 pm, Wolf Behrenhoff
    <> wrote:
    > use List::Util qw(first);
    > my @dates=qw(abc 01/02 02/03 de);
    > say first {/\d\d/} reverse @g'


    Yep, exactly right. Passing reverse(@g) to first() is a nice touch.

    Thanks, CC.
    ccc31807, Jul 19, 2012
    #3
  4. ccc31807 <> writes:
    > On Jul 19, 12:35 pm, Wolf Behrenhoff
    > <> wrote:
    >> use List::Util qw(first);
    >> my @dates=qw(abc 01/02 02/03 de);
    >> say first {/\d\d/} reverse @g'

    >
    > Yep, exactly right. Passing reverse(@g) to first() is a nice touch.


    The same can be achieved with just about as little code without
    loading an additional module and performing several subroutine calls
    and even without creating the intermediate reverted list

    ------------
    use Benchmark;
    use List::Util qw(first);

    my @g = qw(ab 02 03 ee);

    timethese(-10,
    {
    first => sub {
    return first {/\d\d/} reverse(@g);
    },

    inline => sub {
    my $g;

    /\d\d/ and $g = $_, last for reverse(@g);
    return $g;
    },

    inplace => sub {
    my ($g, $n);

    $n = @g;
    { $g[--$n] =~ /\d\d/ and $g = $g[$n], last while ($n--); }

    return $g;
    }});
    ------------

    [The additional block in the last sub is necessary because last works
    with a for-modifier but doesn't work with while-modifier/ 5.10.1]
    Rainer Weikusat, Jul 19, 2012
    #4
  5. Rainer Weikusat <> writes:

    [...]


    > { $g[--$n] =~ /\d\d/ and $g = $g[$n], last while ($n--); }


    The [--$n] was left-over from a slightly different variant and must
    not actually be there.
    Rainer Weikusat, Jul 19, 2012
    #5
  6. ccc31807

    ccc31807 Guest

    On Jul 19, 1:42 pm, Rainer Weikusat <> wrote:
    > The same can be achieved with just about as little code without
    > loading an additional module and performing several subroutine calls
    > and even without creating the intermediate reverted list


    I am picking these three values from a CSV file, which contains
    several other array-types of things, e.g. email addresses and phone
    numbers, that I can sift through with regular expressions. The
    particular problem I had was that I have several dates in exactly the
    same format. All of these consist of exactly one value, except for
    this particular one. What I get from the database is an indeterminate
    list of possible values, which number I limit to 3 after looking at
    the data.

    The insight I missed was simply reversing the list. It's so obvious
    now that I'll a little embarrassed that I missed it.

    Thanks for your suggestion, CC.
    ccc31807, Jul 19, 2012
    #6
    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. senthil
    Replies:
    5
    Views:
    1,361
    senthil
    Jan 24, 2004
  2. Jan De Ceuster
    Replies:
    5
    Views:
    4,686
    Thomas Stanka
    Jan 13, 2005
  3. mathieu
    Replies:
    13
    Views:
    795
    terminator
    Nov 10, 2007
  4. mathieu
    Replies:
    2
    Views:
    539
    mathieu
    Nov 8, 2007
  5. Terry Michaels
    Replies:
    4
    Views:
    153
    w_a_x_man
    Oct 16, 2010
Loading...

Share This Page