Why doesn't Perl's "sort" put these hash keys in numeric order?

10,497

sort always defaults to string comparison.

If you want a numeric sort, you have to be explicit.

sort {$a <=> $b} (keys %hash)
Share:
10,497
Haiyuan Zhang
Author by

Haiyuan Zhang

Updated on June 28, 2022

Comments

  • Haiyuan Zhang
    Haiyuan Zhang almost 2 years

    Consider:

    #!/usr/bin/perl
    use strict;
    use warnings;
    
    my %hash;
    foreach (1 .. 10) {
        $hash{$_} = $_;
    }
    foreach(sort(keys %hash)) {
        print $_ . ":  " . "$hash{$_}" . "\n";
    }
    

    When I execute the above code, the result is as below:

    1:  1
    10:  10
    2:  2
    3:  3
    4:  4
    5:  5
    6:  6
    7:  7
    8:  8
    9:  9
    

    I expect "10: 10" to be the last one that is printed. Why does Perl give me a surprise in this case?

    • jrockway
      jrockway about 14 years
      A hash with keys 1..10 is called an array.
  • Shailesh
    Shailesh about 14 years
    Perl stores them both as strings and as numbers. The problem here is that by default sort sorts the strings.
  • Jacob
    Jacob about 14 years
    The keys of a hash are stored as strings, but even if they were stored as numbers sort still sorts using string comparison.
  • brian d foy
    brian d foy almost 13 years
    Hash keys aren't SVs, so they don't have the same magic as normal Perl scalars. This is why, for instance, you can untaint strings by using them as a hash key and getting them back out with keys().
  • andeyatz
    andeyatz almost 13 years
    If my current understanding is correct aren't they stored as const char* key or at least the C methods for interacting with hashes seem to want this.
  • Thawn
    Thawn over 7 years
    This answer would be way more helpful, if it provided a solution. Otherwise, just delete it, it does not add any useful information and leaves the reader to resort to Quentins answer for a solution and a link to the proper explanation.