in reply to Split a string into a list of lists
If you really want to do it in one, then the following is a way:
The thing to watch out for with nested maps is the reuse of $_, but in this case it's fine.my @array = (undef, map([undef, map($_-64, unpack('C3', $_))], unpack('(A3)*', $string)) +) ;
Just for the hell of it, I threw a little benchmarking at it:
Rate W1SDM GrandFather GMCH
W1SDM 7.59/s -- -30% -48%
GrandFather 10.9/s 43% -- -25%
GMCH 14.6/s 93% 34% --
which tells you that this can go almost twice as fast if you throw certain amount of magic at it. The question is: does this affect the price of cocoa ? And the other question is: if so, was the effect worth the effort ?
Update: ah... same trick as AnomalousMonk above.
use strict ; use warnings ; my $string = "BEHACJBDLCENADFEGOFHQAGIHJRBIKJLSCKMLNTDMOFNPOQTGPRIQSKR +TMPS"; my @results = () ; collect('W1SDM', W1SDM($string)) ; collect('GrandFather', GrandFather($string)) ; collect('GMCH', GMCH($string)) ; printf("%12s %12s %12s\n", @$_) foreach @results ; use Benchmark qw(cmpthese) ; cmpthese(100, { W1SDM => sub { W1SDM($string) for (1..100 +0) }, GrandFather => sub { GrandFather($string) for (1..100 +0) }, GMCH => sub { GMCH($string) for (1..100 +0) }, } ) ; sub collect { my ($t, $r) = @_ ; push @{$results[0]}, $t ; push @{$results[$_]}, sprintf "%02d %02d %02d", @{$r->[$_]}[1..3] fo +r (1..$#$r); } ; sub W1SDM { my ($string) = @_ ; my @array = split //, $string; my @result = () ; for my $i (1..20) { for my $j (1..3) { $result[$i][$j] = ord(shift(@array)) - 64; } } return \@result ; } ; sub GrandFather { my ($string) = @_ ; my @array = (undef); push @array, [0, map {ord ($_) - 64} split '', substr $string, 0, 3, + '' ] while length $string; return \@array ; } ; sub GMCH { my ($string) = @_ ; my @array = (undef, map([undef, map($_-64, unpack('C3', $_))], unpack('(A3)*', $st +ring))) ; return \@array ; } ;
|
|---|