Re: modify the contents of an array
by blazar (Canon) on Sep 29, 2005 at 11:29 UTC
|
if you trust those dates to be in the format above, then
$_=join '/', unpack 'A2' x 3, $_ for @arr;
| [reply] [d/l] |
Re: modify the contents of an array
by Joost (Canon) on Sep 29, 2005 at 11:21 UTC
|
What have you tried? What are you having trouble with? You can use a s/// substitution. Take a look at perlretut.
s!(\d\d)(\d\d)(\d\d)!$1/$2/$3! for @array;
| [reply] [d/l] |
Re: modify the contents of an array
by prasadbabu (Prior) on Sep 29, 2005 at 11:18 UTC
|
@arr = ('092205', '092305', '092605');
map {s/^(\d{2})(\d{2})(\d{2})/$1\/$2\/$3/} @arr;
$" ="\n";
print "@arr";
| [reply] [d/l] |
|
|
No it won't. It will print the return values of those s///'s which happens to be 1.
Also from perlstyle:
Avoid using grep() (or map()) or `backticks` in a void context,
that is, when you just throw away their return values. Those func-
tions all have return values, so use them. Otherwise use a fore-
ach() loop or the system() function instead.
| [reply] [d/l] [select] |
|
|
You would be right if prasadbabu had written:
@arr = map {s/^(\d{2})(\d{2})(\d{2})/$1\/$2\/$3/} @arr;
But he didn't. He rightly ignored the return values of s/// (if you write s/^(\d{2})(\d{2})(\d{2})/$1\/$2\/$3/ for @arr, you are ignoring the return value of s/// just as much as when using map in void context), and went of the side effects of s/// - the main feature of s///. | [reply] [d/l] [select] |
|
|
|
|
|
|
|
blazar you are absolutely right. But the above coding works for me, i tested and then only posted.
Hereafter i try to avoid these kind of mistakes.
| [reply] |
|
|
| [reply] [d/l] |
Re: modify the contents of an array
by Skeeve (Parson) on Sep 29, 2005 at 12:07 UTC
|
Just to add my 2 Euro-Cent:
chomp(@array=<DATA>);
s:(..)(?!$):$1/:g for @array;
print join "\n", @array, '';
__DATA__
092205
092305
092605
nonsense
Yes! This will create nonsense for non matching lines, like the last one. But I wanted to come up with a shorter RE ;-)
$\=~s;s*.*;q^|D9JYJ^^qq^\//\\\///^;ex;print
| [reply] [d/l] [select] |
|
|
Hi,
Your solution seems to be working perfectly but I am still wondering how it happened.I am a beginner in perl ,if you dont mind can you just explain me the solution
| [reply] |
|
|
| [reply] [d/l] |
|
|
Re: modify the contents of an array
by srdst13 (Pilgrim) on Sep 29, 2005 at 11:22 UTC
|
my @dates = (qw/092205 092305 092605/);
my @newdates;
foreach my $date (@dates) {
my ($month,$day,$year) = ($date =~ /(\d\d)(\d\d)(\d\d)/);
push @newdates,join('/',$month,$day,$year);
}
Of course, you can do any particular manipulation of $month,$day,$year that you like, such as changing $year to its 4-digit equivalent, etc.
Sean | [reply] [d/l] |
Re: modify the contents of an array
by tomazos (Deacon) on Sep 29, 2005 at 11:44 UTC
|
Consider whether in the larger picture of your code using one of the Date:: modules may be a better approach.
It may or may not be.
-Andrew.
| [reply] [d/l] |
Re: modify the contents of an array
by dannoura (Pilgrim) on Sep 29, 2005 at 14:45 UTC
|
my @arr = qw/092205 092305 092605/;
foreach (@arr) {$_ = sprintf "%d%d/%d%d/%d%d", split //}
print "@arr";
| [reply] [d/l] |
|
|
Even slower than the s/// suggestion.
#!/usr/bin/perl
use strict;
use warnings;
use Benchmark qw 'cmpthese';
our @dates = (qw [092205 092305 092605]) x 100;
our (@sub, @pck, @mth, @spf,);
cmpthese(-10, {
sub => '@sub = @dates; for (@sub) {s{(\d{2})(\d{2})(\d{2})}{$1/$2/
+$3}}',
pck => '@pck = @dates; for (@pck) {$_ = join "/", unpack "A2 A2 A2
+", $_}',
mth => '@mth = @dates; for (@mth) {$_ = join "/", /../g}',
spf => '@spf = @dates; for (@spf) {$_ = sprintf "%d%d/%d%d/%d%d",
+split //}',
});
__END__
Rate spf sub mth pck
spf 368/s -- -33% -60% -69%
sub 548/s 49% -- -40% -53%
mth 909/s 147% 66% -- -22%
pck 1171/s 218% 114% 29% --
| [reply] [d/l] |
Re: modify the contents of an array
by radiantmatrix (Parson) on Sep 29, 2005 at 15:11 UTC
|
It appears blazar has the best approach. I added data validation to, and bencmarked, the two main solutions (regexes and unpack), as well as doing the same thing with sprintf (just for fun).
@my_array = <DATA>;
use Benchmark ':all';
sub regex_method {
my $array = [@_];
for (@$array) {
next unless /^\d{6}\s*$/; ## validate data
s:(\d{2})(?!$):$1/:g;
}
}
sub sprint_method {
my $array = [@_];
for (@$array) {
next unless /^\d{6}\s*$/; ## validate data
$_ = sprintf "%d%d/%d%d/%d%d", split('',$_);
}
}
sub unpack_method {
my $array = [@_];
for (@$array) {
next unless /^\d{6}\s*$/; ## validate data
$_=join '/', unpack 'A2' x 3, $_ for @arr;
}
}
cmpthese( 50000, {
'regex' => sub { regex_method(@my_array) },
'sprintf' => sub { sprint_method(@my_array) },
'unpack' => sub { unpack_method(@my_array) },
});
__DATA__
010203
020304
012398
122399
With these results (representative of many runs):
Rate sprintf regex unpack
sprintf 20383/s -- -23% -79%
regex 26441/s 30% -- -73%
unpack 96899/s 375% 266% --
<-radiant.matrix->
Larry Wall is Yoda: there is no try{} (ok, except in Perl6; way to ruin a joke, Larry! ;P)
The Code that can be seen is not the true Code
"In any sufficiently large group of people, most are idiots" - Kaa's Law
| [reply] [d/l] [select] |
Re: modify the contents of an array
by ryanc (Monk) on Sep 30, 2005 at 16:27 UTC
|
@arr = ('092205', '092305', '092605');
$_ = join "/", unpack("a2a2a2", $_) for @arr;
later on:
print "$_\n" for @arr;
to verify the values.
should work and is nice and small.
later.
ryanc
| [reply] [d/l] [select] |
|
|
oops, didn't read the reply above. looks like someone
already offered up the 'unpack' way.
| [reply] |