McMahon has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks...

I have an array of strings. I want to lowercase all elements of the array. I tried
@array = lc @array;

but it didn't DWIM.

Obviously I could do a foreach over all the elements of @array, but I just wonder if there's a niftier way to accomplish this.

Thanks...

Replies are listed 'Best First'.
Re: lc entire contents of array?
by Limbic~Region (Chancellor) on Mar 30, 2004 at 15:53 UTC
    McMahon,
    $_ = lc for @array;
    This is likely more efficient than map - at least in newer versions of Perl.

    Cheers - L~R

      It will be more effecient because it doesn't allocate a new array, then deallocate the previous array. Aliasing is a good thing. :-)

      That said, I personally think that map is more self-documenting and easier to read. $_ = lc for @array; could really use a comment about aliasing in production code.

      ------
      We are the carpenters and bricklayers of the Information Age.

      Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

      What counts as newer versions? I find that map whups for's sorry ass in benchmarks under 5.8.0 and 5.8.2.

      You will have to excuse me; I'm about to return to my roots as a Fortran programmer, where all that matters is speed ...

      --
      bowling trophy thieves, die!

        What counts as newer versions? I find that map whups for's sorry ass in benchmarks under 5.8.0 and 5.8.2.

        Eh?

        use Benchmark; @a = qw(the quick brown fox jumps over the lazy dog); timethese(1000000, { 'for' => '$_ = lc for @a', 'map' => '@a = map lc, @a', }); $ perl580 /tmp/p Benchmark: timing 1000000 iterations of for, map... for: 20 wallclock secs (19.28 usr + 0.02 sys = 19.30 CPU) @ 51 +813.47/s (n=1000000) map: 47 wallclock secs (47.85 usr + 0.02 sys = 47.87 CPU) @ 20 +889.91/s (n=1000000)
        Willard B. Trophy,
        I think you assumed by efficient I meant faster. There are all kinds of ways to be efficient. Typically you trade memory for speed. As dragonchild points out, the map creates a temporary list. I say newer versions of Perl because older versions of Perl, it is my understanding, did the same thing in for loops.

        Cheers - L~R

Re: lc entire contents of array?
by dragonchild (Archbishop) on Mar 30, 2004 at 15:51 UTC
    This is where map comes in handy.
    @array = map { lc } @array;

    ------
    We are the carpenters and bricklayers of the Information Age.

    Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

      Maybe it's just me, but I hardly ever use the map BLOCK form; it just doesn't read as well for me as
      @array = map lc, @array
Re: lc entire contents of array?
by sweetblood (Prior) on Mar 30, 2004 at 18:28 UTC
    Another approach would be to convert to lowercase when you populate the array
    push @array, lc($_)

    Cheers!

Re: lc entire contents of array?
by ccn (Vicar) on Mar 30, 2004 at 15:56 UTC
    since perldoc -f lc says nothting about lc LIST there is the only way exists $_ = lc foreach @array

    Update: @array = map{lc} @array is much more readable form of this translation

      If you want the more efficient approach of for/foreach (which uses aliasing) with the readability of map, don't use the short form of for! This is about as good as map and still looks clean.

      foreach $elem (@array) { $elem = lc $elem; }

      Sadly readability (map/foreach) and efficient terse perlishness (the examples ending in for) are often not the same, and given the choice, I'd stick with the map. Yet, the foreach is much more flexible and readable in the long run, and is more readable for non-Perl folks as well. It may prove to be the best option in the long run, if not as shiny looking as the others.

Re: lc entire contents of array?
by Anonymous Monk on Mar 31, 2004 at 04:30 UTC
    You can lowercase each variable in the array in your condition statement
    foreach $arrayitem (@array) { lc($arrayitem); doOtherStuff....etc }
Re: lc entire contents of array?
by Anonymous Monk on Mar 31, 2004 at 13:44 UTC
    @array=map { lc } @array
A reply falls below the community's threshold of quality. You may see it by logging in.