Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

elegant way of getting last REAL value of an array

14 views
Skip to first unread message

ccc31807

unread,
Jul 19, 2012, 12:11:34 PM7/19/12
to
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.

Wolf Behrenhoff

unread,
Jul 19, 2012, 12:35:13 PM7/19/12
to
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

ccc31807

unread,
Jul 19, 2012, 12:41:27 PM7/19/12
to
On Jul 19, 12:35 pm, Wolf Behrenhoff
<NoSpamPleaseButThisIsVal...@gmx.net> 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.

Rainer Weikusat

unread,
Jul 19, 2012, 1:42:12 PM7/19/12
to
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

unread,
Jul 19, 2012, 1:51:39 PM7/19/12
to
Rainer Weikusat <rwei...@mssgmbh.com> 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.

ccc31807

unread,
Jul 19, 2012, 2:14:22 PM7/19/12
to
On Jul 19, 1:42 pm, Rainer Weikusat <rweiku...@mssgmbh.com> 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.
0 new messages