On Jul 28, 2004, at 12:55 PM, John West wrote:
James Edward Gray II <[EMAIL PROTECTED]>
On Wed, 28 Jul 2004 12:41:08 -0500, James Edward Gray II wrote
I'm never one to abuse working code, but if your definition of "better" has something to do with sorter, a simple Schwartzian Transformation seems to work:
@input = map { $_->[0] } sort { lc($a->[1]) cmp lc($b->[1]) } map { m/\.([^.]+)$/ ? [$_, $1] : [$_, ''] } @input;
Thanks for the suggestion. I'm not really sure what I mean by better - seems like there are tradeoffs between readability, performance and length; mine is too long. Unfortunately I can't follow this code (I'm not a big fan of map or grep) so I probably wouldn't take this approach unless it really improves performance.
Not a "fan" of map() and grep() or just don't understand them? I'm hoping it's the second, since the first doesn't make much sense to me. Luckily, we can fix the second.
map() is generally just a shorthand for a foreach loop. You feed it a list and a chunk of processing code. It runs the code on each item in the list and spits out a list that is the results the code returned for each item. Example:
my @names = qw(JAMES BOB JEFF);
my @title_case = map { "\u\L$_" } @names; # process each name
print "@title_case\n"; # prints James Bob Jeff
Let's apply that thinking to demystify the code I offered you. It's easier to read that code bottom to top, so let's start with:
map { m/\.([^.]+)$/ ? [$_, $1] : [$_, ''] } @input;
That processes each element of the array input. The processing code looks for an extension and returns a two element array (by reference) that contains the original string in the first slot and the extension in the second (or an empty string, if none could be found). Our modified list of originals and extensions side-by-side is then handed up the chain to:
sort { lc($a->[1]) cmp lc($b->[1]) }
Are you a "fan" of sort()? It works just like map() and grep().
You feed it a list, a condition or conditions you want it sorted on and it returns the results. My condition here is simply what you asked for, by extension case-insensitively. We have our answer at this point, but not in the format expected so we feed it to one more map():
@input = map { $_->[0] }
This is simply the reverse of the first map(). Where it turned everything into a two-part list (original and extension), this one returns everything to it's original format, discarding referenced arrays and extensions. The result of that final operation is then store back in the array.
grep() is more a list filtering tool. Feed it a list, tell it what you're looking for, and you get just those elements back. Example:
my @numbers = (104, 3, 102, 1, 100);
my @small_numbers = grep { $_ < 10 } @numbers; # search list
print "@small_numbers\n"; # prints 3 1
map() and grep() are powerful tools, because they allow us to specify what work we want done. You can argue that they hurt readability in some cases, as long as I can argue that they help it in others. Eventually, when you're learning any language, you have to start picking up the slang too, so you can speak it like the pros do. Nothing wrong with that.
Work with them a little and see if you can't put them to good use. I think you'll surprise yourself and hopefully, become a "fan"...
James
-- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] <http://learn.perl.org/> <http://learn.perl.org/first-response>