in reply to Re^2: modify the contents of an array
in thread modify the contents of an array

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

Replies are listed 'Best First'.
Re^4: modify the contents of an array
by blazar (Canon) on Sep 29, 2005 at 12:15 UTC
    You're perfectly right. I overlooked that. Hence here are my partial apologies to prasadbabu. Partial, because map still isn't the best tool for that task.
      Well, that depends on how you describe "best tool". If best tool means "fastest" or least resource sensitive, then perl isn't the best tool for the job, as it isn't as fast as C.
        Let's benchmark:
        #!/usr/bin/perl use strict; use warnings; use Benchmark qw 'cmpthese'; our @dates = qw [092205 092305 092605]; our (@mb, @me, @fb, @fe); cmpthese(-1, { map_block => '@mb = @dates; map {s{(\d{2})(\d{2})(\d{2})}{$1/$2/$3 +}} @mb', map_expr => '@me = @dates; map s{(\d{2})(\d{2})(\d{2})}{$1/$2/$3 +}, @me', for_block => '@fb = @dates; for (@fb) {s{(\d{2})(\d{2})(\d{2})}{$1 +/$2/$3}}', for_expr => '@fe = @dates; s{(\d{2})(\d{2})(\d{2})}{$1/$2/$3} for + @fe', }); die unless "@mb" eq "@me" && "@mb" eq "@fb" && "@mb" eq "@fe"; __END__ Rate for_block for_expr map_block map_expr for_block 43115/s -- -1% -2% -6% for_expr 43530/s 1% -- -1% -5% map_block 43840/s 2% 1% -- -5% map_expr 45948/s 7% 6% 5% --
        Running it a few more times shows the expression form of map being slightly faster than any of the others, and even the block version of map not doing too bad:
        Rate map_block for_expr for_block map_expr map_block 43050/s -- -1% -5% -7% for_expr 43631/s 1% -- -4% -6% for_block 45271/s 5% 4% -- -2% map_expr 46419/s 8% 6% 3% -- Rate for_expr for_block map_block map_expr for_expr 42309/s -- -3% -5% -7% for_block 43530/s 3% -- -3% -5% map_block 44660/s 6% 3% -- -2% map_expr 45583/s 8% 5% 2% -- Rate for_block for_expr map_block map_expr for_block 43115/s -- -1% -3% -7% for_expr 43530/s 1% -- -2% -6% map_block 44246/s 3% 2% -- -5% map_expr 46419/s 8% 7% 5% --
        Things might be different on your machine, but the difference in performance is too small to regard one as better than the other.

        Now, if you really want to go for speed, your concern should not be the difference between 'for' and 'map', but the difference between 's///' and something else. For instance, let's introduce an additional clause in the benchmark:

        pack => '@pk = @dates; @pk = map {join "/", unpack "A2 A2 A2", $_} @pk +'
        This leads to the results:
        Rate for_expr for_block map_block map_expr pack for_expr 42309/s -- -0% -2% -9% -48% for_block 42309/s -0% -- -2% -9% -48% map_block 43115/s 2% 2% -- -7% -47% map_expr 46394/s 10% 10% 8% -- -43% pack 80736/s 91% 91% 87% 74% --
        It dwarves the difference between map and for.
        briefly, map and grep are to be used for their return value. Or else a for loop will do. Even the perlstyle page mentions that...