http://qs1969.pair.com?node_id=127553

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

I have a hash of data, hashes and arrays. Is it possible to get Data::Dumper to give me output sorted on the key value of the hash? What would the syntax be?

The hash looks something like(untested) but a whole lot longer:

%hash = ( x=> 'line 1', z=> [ 1, 2, 4], y=> { file=> 'test.txt', length=> 200, type => 'ASCII' }, a=> 'line 2' );

and I would like Data::Dumper "style" output sorted on the hash keys.

g_White

Replies are listed 'Best First'.
(Ovid) Re: Sorting Data::Dumper Output
by Ovid (Cardinal) on Nov 26, 2001 at 20:07 UTC

    Since hashes are inherently unordered (well, as far as the programmer is concerned), you're going to have some trouble doing that cleanly. One unclean way of doing that (for top level keys only) is:

    print Dumper map [$_, $hash{ $_ }], sort keys %hash;

    However, since that breaks name/value pairs into a series of array refs, you'll probably be less than pleased with the output. You could also try Tie-SortHash-1.01. I have no idea if that would work, but the documentation suggests to me that it might.

    Cheers,
    Ovid

    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

Re: Sorting Data::Dumper Output
by tachyon (Chancellor) on Nov 26, 2001 at 20:50 UTC

    Sice Data::Dumper uses XS (ie is written in C) hacking the source to get what you want is less than trivial. I wanted this myself a while ago. Here is a hack that reformats the standard Data::Dumper output and sorts on keys - it produces the output you expect, just sorted:

    Update

    Made sub recursive and added some options for numeric, alpha or auto choice sort and optional array sorting. It now sorts all elements to whatever depth

    Update

    Code has been moved to snippets Sort Data::Dumper Output and patched to correctly handle AoH and AoA constructs

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Re: Sorting Data::Dumper Output
by Rich36 (Chaplain) on Nov 26, 2001 at 20:11 UTC
    Similar to Ovid's answer, but different syntax...
    use Data::Dumper; %hash = ( x=> 'line 1', z=> [ 1, 2, 4], y=> { file=> 'test.txt', length=> 200, type => 'ASCII' }, a=> 'line 2' ); foreach(sort{ $a cmp $b } keys(%hash)) { print Dumper($hash{$_}); }

    Rich36
    There's more than one way to screw it up...

Re: Sorting Data::Dumper Output
by blakem (Monsignor) on Nov 26, 2001 at 23:59 UTC
    Depending on what you are doing, you might be able to use Storable's Canonical Representation like this:
    #!/usr/bin/perl use strict; use Storable; $Storable::canonical = 1; my %hash = ( x=> 'line 1', z=> [ 1, 2, 4], y=> { file=> 'test.txt', length=> 200, type => 'ASCII' }, a=> 'line 2' ); store \%hash, 'hashfile.txt';
    While the stored file isn't human readable, it will always be the same given the contents of the hash.

    -Blake

Re: Sorting Data::Dumper Output
by chipmunk (Parson) on Nov 27, 2001 at 10:12 UTC
    You might want to give Data::Dump a try. It produces the keys in sorted order when dumping a hash. As the documentation says, the module grew out of frustration with Data::Dumper. :)
Re: Sorting Data::Dumper Output
by frankus (Priest) on Nov 26, 2001 at 20:31 UTC

    IIRC there is a module for ordering hashes: libtie-ixhash-perl on Debian woody, give me a mo, I'll find the module name.

    here

    --

    Brother Frankus.

    ¤

Re: Sorting Data::Dumper Output
by Hofmator (Curate) on Nov 27, 2001 at 16:17 UTC
Re: Sorting Data::Dumper Output
by shotgunefx (Parson) on Nov 27, 2001 at 12:53 UTC
    Wish I could ++ this question twice. I've often found it frustrating. I actually tried looking into actually fixing this yesterday out of frustration via $Data::Dumper::Toaster.
    (I'm working on a CGI with a complex data structure that takes four 1024x768 screens to print and has over 30 application screens. Easier to tack it on to the end of the page for Debug purposes.)

    Trying to examine the output is tedious to put it mildly.

    -Lee

    "To be civilized is to deny one's nature."

      Thanks for all the help, this is what turned out to be the easiest fix, Ovid's suggestion
      use Data::Dumper; use Tie::SortHash; %hash = ( x=> 'line 1', z=> [ 1, 2, 4], y=> { file=> 'test.txt', length=> 200, type => 'ASCII' }, a=> 'line 2' ); tie %hash, 'Tie::SortHash', \%hash; print Dumper(\%hash);

      and all came out as I desired.

      g_White
        It should always be that easy! Didn't think a tie would work. I just "ass"umed that Data::Dumper was walking the structure in a clandestine fashion.

        -Lee

        "To be civilized is to deny one's nature."

        Update Doesn't work for complex stuctures like HoH :(
        I guess I'll try Data::Denter