elegant way of getting last REAL value of an array

C

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.

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

Wolf Behrenhoff

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
 
C

ccc31807

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

Rainer Weikusat

ccc31807 said:
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;
}});
 
R

Rainer Weikusat

[...]

{ $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.
 
C

ccc31807

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.
 

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

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top