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

I have a hash of names+values.

Whats the common way to sort the hash alphabetically? I don't want to print it out, I just want a sorted hash for use later.

I assume a foreach is the way to go?

Replies are listed 'Best First'.
Re: Hash sorting
by Zaxo (Archbishop) on May 14, 2006 at 22:21 UTC

    Hashes won't preserve order. You can use Tie::IxHash, which sets up a different, order preserving, data structure with hash semantics.

    You could keep a sorted array of keys from your hash, instead.

    my @key_sorted = sort keys %hash; #or my @val_sorted = sort {$hash{$a} cmp $hash{$b}} keys %hash;

    After Compline,
    Zaxo

      Zaxo,
      Tie::IxHash is not designed for hash sorting which this question is about. It does allow you to preserve insertion order so that would require you to know in advance every single key/val pair that you want for the hash and enter them in that order. Ok, it does provide extremely rudimentary sorting capability (asciibetically by keys or vals), but that is more of an afterthought.

      If you want your hash to stay sorted using an arbitrary criteria regardless of what you do to it, use Tie::Hash::Sorted.

      Cheers - L~R

Re: Hash sorting
by GrandFather (Saint) on May 14, 2006 at 22:45 UTC

    You need to consider what you really want to do with your data. A hash is a bag that holds a bunch of data that you access using a key. There is no 'order' to the data. In fact, what order it may have will change as data is added and removed from the bag.

    If you want fast access to a chunk of data given a key, use a hash. If you want to preserve the order of a list of stuff, use an array. If you want to do both use a tied hash (Tie::IxHash as suggested by Zaxo). Note though that a tied hash does neither job as well as the built in structures.

    Most often though all you need is to generate a sorted list of keys when you need them using something like sort keys %hash. If what you want is to sort by the values and don't care about the keys you can sort values %hash. But really, any general advice is likely to be overtaken by your actual application. To get solid advice, provide a small sample of the sort of data and the code that you are using. Mention too how much data there is and how often you may need to access the data in sorted order. All those things influence the choices that may be made.


    DWIM is Perl's answer to Gödel
Re: Hash sorting
by aufflick (Deacon) on May 15, 2006 at 07:25 UTC
    Assuming you want to sort the data by the key, the idiom you're probably looking for is something like:
    my %hash; # use the hash like normal - perl will keep it in whatever # order is the most useful for the runtime foreach my $key (sort keys %hash) { print $hash{$key}; }
    Unless your hash is huge (like, tens of thousands of keys), it will almost definately be faster to sort the keys each time you want to access it rather than keep a tied hash (or some other custom datatype) in the sort order that you want.
      Thanks, printing it out when needed will do just fine,
      however I need to print both the key names and values.
      Apologies as I'm new to perl.
        however I need to print both the key names and values

        Then print both :)

        foreach my $key (sort keys %hash) { print "$key : $hash{$key}\n"; }

        Update: typo fixed. Thanks to johngg for pointing it out.

        --
        <http://dave.org.uk>

        "The first rule of Perl club is you do not talk about Perl club."
        -- Chip Salzenberg

      Got it!

      Thanks for your patience :)
A reply falls below the community's threshold of quality. You may see it by logging in.