Brethren--

I'm lazy. So whenever I need to sort a hash, I don't want to have to think about the mechanics of sorting it...I just want it done.

I've been able to get away with just needing to sort one column/field in my hashes but recently needed to be able to sort on multiple columns so I modified my hash sorting subroutine to the below code after pilfering the idea (using "or" to string together multiple sort criterias) presented by lhoward in this node and after getting some great help at this node.

Hope this can help some other lazy monks.

mdog

$hash{'Me'}->{"name"} = "Me"; $hash{'Me'}->{"number"} = "7.7"; $hash{'Chuck'}->{"name"} = "Chuck"; $hash{'Chuck'}->{"number"} = "7.7"; $hash{'Zed'}->{"name"} = "Zed"; $hash{'Zed'}->{"number"} = "7.7"; $hash{'Wife'}->{"name"} = "Wife"; $hash{'Wife'}->{"number"} = "7.6"; $hash{'Dad'}->{"name"} = "Dad"; $hash{'Dad'}->{"number"} = "53"; $hash{'Michael'}->{"name"} = "Michael"; $hash{'Michael'}->{"number"} = "24"; my @sortedKeys = SortHashByMultipleColumns(\%hash,["number:asc","name: +asc"]); foreach my $sortedKey(@sortedKeys){ print $hash{$sortedKey}->{'number'} . " " . $hash{$sortedKey}->{'n +ame'} . "\n"; } sub SortHashByMultipleColumns{ my($hashRef,$sortInfoAR) = @_; my $sortCriteria; foreach my $sortInfo(@$sortInfoAR){ my($sortColumn,$sortDirection) = split(/\:/,$sortInfo); my $sortType; # VERIFY THAT THIS IS A VALID COLUMN if(! defined $hashRef->{((keys %$hashRef))[0]}->{$sortColumn}) +{ print "SortHashByMultipleColumns Error: $sortColumn is not + a column in this hash.\n"; exit(0); # VALID COLUMN, FIGURE OUT IF IT IS A NUMERIC COLUMN OR ALPHA } else { if($hashRef->{((keys %$hashRef))[0]}->{$sortColumn} =~ /^\ +d+/){ $sortType = "numeric"; } else { $sortType = "alpha"; } } # want to sort a number if($sortType eq "numeric"){ # sort it asc if($sortDirection =~ /asc/i){ # add an or if we already have something in the sort c +riteria if($sortCriteria){ $sortCriteria .= qq| or |; } $sortCriteria .= '$hashRef->{$a}->{\'' . $sortColumn . + '\'} <=> $hashRef->{$b}->{\'' . $sortColumn . '\'}'; # sort it desc } else { # add an or if we already have something in the sort c +riteria if($sortCriteria){ $sortCriteria .= qq| or |; } $sortCriteria .= '$hashRef->{$b}->{\'' . $sortColumn . + '\'} <=> $hashRef->{$a}->{\'' . $sortColumn . '\'}'; } # want to sort it by alpha } else { # sort it asc if($sortDirection =~ /asc/i){ # add an or if we already have something in the sort c +riteria if($sortCriteria){ $sortCriteria .= qq| or |; } $sortCriteria .= '$hashRef->{$a}->{\'' . $sortColumn . + '\'} cmp $hashRef->{$b}->{\'' . $sortColumn . '\'}'; # sort it desc } else { # add an or if we already have something in the sort c +riteria if($sortCriteria){ $sortCriteria .= qq| or |; } $sortCriteria .= '$hashRef->{$b}->{\'' . $sortColumn . + '\'} cmp $hashRef->{$a}->{\'' . $sortColumn . '\'}'; } } } my $sortfunc = eval "sub { $sortCriteria }"; my @sortedKeys = sort $sortfunc keys %$hashRef; return @sortedKeys; }

In reply to Sort Multidimensional Hash By Multiple Columns by mdog

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.