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

Hi monks,
I have a little sort problem. I want to sort keys of a hash by values stored in an anonymous array. If the value is an empty string, I want that the key is sorted to the end of the @sorted. How to change my code?
Thanks
@sorted = map { $_->[1] } sort { $a->[0] cmp $b->[0] } map { [ $all{$_}->[$sortValue], $_ ] } keys %all;

Replies are listed 'Best First'.
Re: sort empty string (||)
by tye (Sage) on Jul 29, 2003 at 17:50 UTC

    Minor improvement over a couple of the solutions provided:

    sort { !length($a->[0]) <=> !length($b->[0]) || $a->[0] cmp $b->[0] }
    (to some, anyway)

                    - tye
Re: sort empty string
by dragonchild (Archbishop) on Jul 29, 2003 at 17:41 UTC
    This is kinda tested. I would test it thoroughly with your data before using it in production.
    sub by_my_criteria { return 1 unless length $a->[0]; return -1 unless length $b->[0]; return $a->[0] cmp $b->[0]; } sorted = map { $_->[1] } sort by_my_criteria map { [ $all{$_}->[$sortValue], $_ ] } keys %all;
    Update: Fixed by_my_criteria() as per tadman's comments via /msg.

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

    Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

    Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

Re: Sort Empty String Last
by tadman (Prior) on Jul 29, 2003 at 17:42 UTC
    Using a custom sort routine, you can redefine the sort behavior for a specific condition. Here's an example of something that always puts empty strings last, but otherwise sorts alphabetically:
    sub by_blanklast { if (!length($a->[0]) ^ !length($b->[0])) { return length($b->[0]) - length($a->[0]); } return $a->[0] cmp $b->[0]; }
    You can use this in your code like this:
     } sort by_blanklast map {
    In my testing, this seems to work like you want.
Re: sort empty string
by pijll (Beadle) on Jul 29, 2003 at 20:36 UTC
    You can use a more complex sort routine. However, any extra code there will be executed for each comparison, O(N log N) times IIRC. As you are using a Schwartzian transform anyway, just make sure that empty strings are mapped to a value that sorts last. E.g. (untested):
    @sorted = map { $_->[1] } sort { $a->[0] cmp $b->[0] } map { [ (length($all{$_}->[$sortValue])? '0' . $all{$_}->[$sortValue] : '1'), $_ ] } keys %all;
Re: sort empty string
by LameNerd (Hermit) on Jul 29, 2003 at 17:37 UTC
    You can alway define your own sort sub. Here's an example I found in the Camel book.
    sub byage { $age{$a} <=> $age{$b}; } @sorted = sort byage @class;