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

Hello, fellow monks.

I have the following bloated code in a cgi script I'm writing:

@filesImage = sort { $a->{name} cmp $b->{name} } @filesImage; @filesAudio = sort { $a->{name} cmp $b->{name} } @filesAudio; @filesText = sort { $a->{name} cmp $b->{name} } @filesText; @filesUnknown = sort { $a->{name} cmp $b->{name} } @filesUnknown; @filesDirectory = sort { $a->{name} cmp $b->{name} } @filesDirectory;

I'm planning to rewrite this code with some references, something along the lines of:

foreach (\@list1, \@list2) { @$_ = sort {$a cmp $b} @$_; }

... but when I've tried to use 'map' for this, just as an excercise, I couldn't find the right syntax to stop map from merging the lists. Out of curiosity, could this be rewritten as a one-liner with map, and if so, how?

Replies are listed 'Best First'.
•Re: simplify sorting of multiple lists
by merlyn (Sage) on Jul 20, 2004 at 16:51 UTC
    If you're treating a lot of things similarly, it's a hint that they are not really separate top-level variables, but rather portions of a larger data structure. In other words, I'd have a hash of arrayrefs containing your individual named arrays.

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

      That's a good idea. I know the chosen variables aren't clean. The problem was indeed that all those lists used to be just one big list (with an extra hash pair per element pointing out the type), but the simple template syntax of HTML::Template required a boolean variable (I use each individual list) to test for whether or not to include the specific html block when the list is empty.

      It's either this or introducing an extra boolean for each type of files. Or trying a different template module, perhaps.

      Ofcourse, I stupidly forgot that I can play a bit with the arguments to the template's function call, to just pass on the list, if I do it this way.

      edit: corrected myself

Re: simplify sorting of multiple lists
by ccn (Vicar) on Jul 20, 2004 at 16:48 UTC
    @$_ = sort {$a cmp $b} @$_ for \@list1, \@list2;

    you can use map of course, but it's a bad style see perldoc perlstyle

    map {@$_ = sort {$a cmp $b} @$_} \@list1, \@list2;
      Ah, thanks for your solution. I was -quite unsuccesfully- trying to use the return value of 'map', so I think the bad style rule doesn't count then. I think the flattening effect of map's return values is what got me stuck. I will use the for-notion, I think. It's quite easy to understand on first sight.