#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2013
    Posts
    39
    Rep Power
    2

    Random order while using hash/keys


    Hello,
    I understand that getting random order is expected when using hash (keys function). Please take a look at my code below

    Code:
    #!/usr/local/bin/perl
    
    use strict;
    use warnings;
    
    my $key = 0;
    my %myhash =
    (
     "1","one",
     "2",2,
     "3","three",
    );
    
    foreach $key(keys %myhash)
    {
     print "key==[$key], value==$myhash{$key}\n";
    }
    I also understand that to get correct order, you should use something like
    Code:
    foreach $key("1","2","3")
    {
     print "key==[$key],value==$myhash{$key}\n";
    }
    But my question is, while using foreach $key(keys %myhash), why do I get the same random output everytime ? Shouldn't it be completely random, as in, different executions of the script should give different order ?

    Thanks.
  2. #2
  3. !~ /m$/
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    May 2004
    Location
    Reno, NV
    Posts
    4,252
    Rep Power
    1810
    Here's what the perl docs say:

    The keys of a hash are returned in an apparently random order. The actual random order is subject to change in future versions of Perl, but it is guaranteed to be the same order as either the values or each function produces (given that the hash has not been modified). Since Perl 5.8.1 the ordering can be different even between different runs of Perl for security reasons (see Algorithmic Complexity Attacks in perlsec).
    There is no correct order for a hash. The order perl is keeping the data in is an internal implementation detail, which should be of no interest to you. That's what the docs are saying.

    It isn't truly random, the order of the data is just not guaranteed. Perl is building the hash representation based on the data being put into it, in order to do quick lookups. If you call 'keys' repeatedly, you may get the same order each time, but it isn't sorted, and it's not returned to you in the order the data was added. It's the order perl decided would lead to quick lookups when you ask for a key.

    The point of a hash structure is to look up data by a named value. If order is important, use an array. You can stack the two data types to build structures that make sense for your application.
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Jun 2012
    Posts
    828
    Rep Power
    496
    The order in which you get the keys is seemingly random, not truly random.

    But if you do not change anything to the hash (don't add or remove elements), you are guaranteed to get always the same order for the keys, each and values functions.

    In the case of your example, an array would make more sense than a hash. You could declare and use it simply as follows:

    Perl Code:
    my @myarray = qw/ one 2 three/;
    print "@myarray"; # prints "one 2 three" (in the right order)


    If you want to print your hash in the order of the sorted keys, this syntax sorting the keys is simpler than what you did:

    Perl Code:
    print "key==[$_], value==$myhash{$_}\n" for sort keys %myhash


    This prints:
    Code:
    key==[1], value==one
    key==[2], value==2
    key==[3], value==three
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2013
    Location
    Pacific Beach, San Diego
    Posts
    3
    Rep Power
    0

    Random Hash Keys


    What is the behavior that you actually want to accomplish?
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2013
    Posts
    39
    Rep Power
    2
    Originally Posted by GeorgeX
    What is the behavior that you actually want to accomplish?
    Hello GeorgeX, not accomplish, but I was thinking that maybe, it gives a different order each time. But the explanation above pretty much cleared and I understand that the order will be based on how perl's hash function/logic fits in for the data I'm giving.

IMN logo majestic logo threadwatch logo seochat tools logo