A nested data structure like this cannot be sorted in the narrow sense of the word. You can sort a list, and you can sort an array by treating it as a list, but you cannot sort a hash. The best thing you can do is its keys, which naturally form a list (if the keys don't matter, you can also sort the values directly).

my @sorted = sort @unsorted; say foreach @sorted; # Output in sorted order

but not this:

my %sorted = sort %unsorted # DOES NOT WORK! say foreach (sort values %unsorted) # workaround (if you don't care ab +out keys) say $sorted{$_} foreach (sort keys { $unsorted{$a} <=> $unsorted{$b} } + %unsorted) # workaround (general)

Let's look at that workaround, though. The reason it works is that there's an easy way to get all the keys of a hash, namely keys (or, for the simpler case, all its values, using values). Is it possible to replicate this with a multilevel structure? Yes, but since you now have to take more than one level into account, it's not so simple anymore; there's no built-in function. The natural way of doing this (natural according to me, anyway) is flattening the keys, so that $data_hash{$key0}[$idx0]{$key1} becomes e.g. $flat_data_hash{"$key0-$idx0-$key1"}, and then working with the resulting structure as before. (If the individual keys matter, have the values of this structure be hashes that contain the value and all the individual keys.)

That's pretty much what you've been doing, except you're also switching keys and values. I don't see a real reason for doing that, and it complicates your code (since values are not guaranteed to be unique, you have to maintain a list of keys for each), so I'd advise against that.

I'll cook up some code to get you started; give me a few minutes. (There may be CPAN modules for this sort of thing, too; I haven't checked.)

Unrelated observation: you don't use strict;, do you? I highly suggest doing so; it'll catch many mistakes. For best results, also use warnings;.

Unrelated observation #2: your posted code doesn't actually work, does it? Your second foreach loop iterates over the keys of %{$data_hash{$key0}}, but %data_hash is supposed to contain (references to) arrays of hashes, not hashes.


In reply to Re: sorting hash of array of hashes by value by AppleFritter
in thread sorting hash of array of hashes by value by Special_K

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.