Hash keys and values โ€‹โ€‹in the correct order

I saw many times the following code snippet to attach a hash to another hash

%hash1 = ('one' => "uno"); %hash2 = ('two' => "dos", 'three' => "tres"); @hash1{keys %hash2} = values %hash2; 

I thought that every time the "values" or "keys" functions were called, their output order was random. If so, then how does the above operator get the keys and values โ€‹โ€‹in the correct order on both sides?

In other words, why is it not possible to get "two" => 'tres' in% hash1 after merging both hashes? Is Perl smart enough to know that if "keys" and "values" are called on the same line, then keys and values โ€‹โ€‹should be specified in the same order?

+7
perl hash
source share
2 answers

See perldoc -f keys

As long as this hash is not modified, you can rely on keys, values, and each to repeatedly return the same order to each other.

+10
source share

A hash is an array of linked lists. The hash function converts the key into a number, which is used as the index of the array element ("bucket") into which the value will be stored. More than one key can hash to the same index (โ€œcollisionโ€), a situation with which linked lists are associated.

The iterator used by keys , values and each returns the elements in the order corresponding to their location in the hash. I assume that it iterates over the linked list in the first bucket, then over the linked list in the second bucket, etc. The point is that it does not randomize the order in which iterates over the hash elements. This is why documents guarantee the following:

As long as this hash is not modified, you can rely on keys, values, and each to repeatedly return the same order to each other.

What is "random" [1] in which is the number of the bucket to which the key will hash. Each hash has a random secret number that outrages the hash function. This leads to the fact that the hash elements are different for each hash and for each program run. [2]

Adding items to the hash can lead to an increase in the number of buckets and can cause the secret number to start (if one of the linked lists becomes abnormally long). Both of these parameters will reorder the elements in this hash.

 $ perl -le' my %h1 = map { $_ => 1 } "a".."j"; my %h2 = map { $_ => 1 } "a".."j"; print keys(%$_) for \%h1, \%h1, \%h2, \%h2; ' hjfeadbigc hjfeadbigc bdgcifjhae bdgcifjhae $ perl -le' my %h1 = map { $_ => 1 } "a".."j"; my %h2 = map { $_ => 1 } "a".."j"; print keys(%$_) for \%h1, \%h1, \%h2, \%h2; ' dcahigjbfe dcahigjbfe gihacdefbj gihacdefbj 

  • This is not entirely random. If you insert two elements into the hash, the second element has a probability of more than 50%, returned after the first iterator.
  • In older versions of Perl, everything was not so random.
+3
source share

All Articles