Is it possible to sort .. hash ... without using any additional, supplementary arrays?

It depends what you want to do with the sorted data?

A hash table cannot he sorted directly, they have no ordering. All you can do is sort the keys.

For a single level hash, if all you want to do with the sorted results is print them out, then you can do that without storing the sorted keys anywhere (other than in the list returned by sort). But if need to remember the sorted ordering, you have to assign the ordered keys somewhere. Typically to an array.

For your multi-level hash, you want to sort the keys of several sub-hashes together, which complicates things. First you need to get all the keys of the subhashes together so they can be sorted. Then you need to obtain the values associated with those keys, and that means remembering which sub-hash each key belongs to. It may (almost certainly is) possible to do this in one pass without creating a temporary array, but it would most likely be horribly complicated and not very efficient.

It sometimes makes sense to live with complication for efficiency; or a lack of efficiency for the sake of clarity. It never makes sense to use a complicated and inefficient route just to save a temporary array.

Assuming a reasonably small hash, I'd do it this way:

{ my @keys = map{ keys %$_ } values %channel_db_files;; my @values = map{ values %$_ } values %channel_db_files;; my @order = sort{ $keys[ $a ] <=> $keys[ $b ] } 0 .. $#keys;; print "$keys[ $_ ]\t$values[ $_ ]" for @order;; } 00001 /foo/oradata/bar/system01.dbf 00002 /foo/oradata/bar/undotbs01.dbf 00003 /foo/oradata/bar/tools01.dbf 00004 /foo/oradata/bar/foodb-data02.dbf 00005 /foo/oradata/bar/xml01.dbf 00006 /foo/oradata/bar/foodb-index11.dbf 00007 /foo/oradata/bar/undotbs02.dbf 00008 /foo/oradata/bar/foodb-data01.dbf 00009 /foo/oradata/bar/foodb-index01.dbf 00010 /foo/oradata/bar/foodb-lob01.dbf

By the time you exit the block, the temporaries will have gone away anyway, and it will likely be both easier to read and more efficient than any mechanism that avoids temporaries.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

In reply to Re: How-to sort nested hash table? by BrowserUk
in thread How-to sort nested hash table? by Scottie

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.