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

Hi guys !

A tricky one. I have an array of hashes (each array entry is a hash reference). The hashes have a key named path which holds as a value a directory path, for example /usr/bin. I need to sort the array by the paths in the hashes. for example:
# if I have: @array = ( { path => '/usr/bin', # I have other keys except the 'path +', but it's not important here }, { path => '/etc/init.d', }, { path => '/root', } );
I need that the '/etc/init.d' "hash" (the hash containg this path) will be first, '/root' second, and of course '/usr/bin' last.
Anyone to the rescue?

Thanks.

Hotshot

Replies are listed 'Best First'.
Re: sorting array of hashes
by Anonymous Monk on Sep 22, 2002 at 11:01 UTC
    You can do it with a custom sort sub:

    @array = sort { $a->{'path'} cmp $b->{'path'} } @array;

Re: sorting array of hashes
by diotalevi (Canon) on Sep 22, 2002 at 14:55 UTC
    This isn't all that hard - you just use a custom sort and prioritize your comparisons by checking for special values first. In this case I use a set of regexes as hash keys and provide a default (3) for the cases that aren't covered. This example steps on the values $aKey, $bKey, $aPri, $bPri - you could modify the code to eliminate the temporary variables.
    %sort_priority = ( qr|^/etc/init.d| => 0, qr|^/root| => 1, qr|^/usr/bin| => 2, qr|.?| => 3 ); @new_array = sort { # Get the matching keys ($aKey) = grep { $a->{'path'} =~ $_ } keys %sort_priority; ($bKey) = grep { $b->{'path'} =~ $_ } keys %sort_priority; # and now their priorities $aPri = $sort_priority{$aKey}; $bPri = $sort_priority{$bKey}; # Now compare based on priority then value ($aPri == $bPri ? $a->{'path'} cmp $b->{'path'} : $aPri <=> $bPri) } @array;
    Update: And of course I forgot that it's a bunch of hash references. Now $a and $b are properly dereferenced