Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Re: Split a string into a list of lists

by gone2015 (Deacon)
on Feb 06, 2009 at 10:32 UTC ( [id://741853] : note . print w/replies, xml ) Need Help??


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:

my @array = (undef, map([undef, map($_-64, unpack('C3', $_))], unpack('(A3)*', $string)) +) ;
The thing to watch out for with nested maps is the reuse of $_, but in this case it's fine.

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 ; } ;