I've seen many times the following piece of code to join 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" function is called, their output order was random. If this is true, how does the statement above gets the keys and values in the right order on both sides?
In other words, why there is not a chance of getting '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 must be given in the same order?
The problem with hash tables is that they don't necessarily store the data in order. For example, if you have retrieved the phone number of “Smith, Jill”, you can't expect the phone number of “Smith, John” to be nearby. This can be a big problem in practice.
Entries in a hash are often referred to as key-value pairs. This creates an associative representation of data. Most commonly, a hash is created using symbols as keys and any data types as values.
Hashing is the process of transforming any given key or a string of characters into another value. This is usually represented by a shorter, fixed-length value or key that represents and makes it easier to find or employ the original string. The most popular use for hashing is the implementation of hash tables.
The hashing key is the raw data in which to be hashed. The hashing algorithm is the algorithm which performs a function to convert the hash key to the hash value. the hash value is what is produced as a result of the hash key being passed into the hashing algorithm.
See perldoc -f keys
So long as a given hash is unmodified you may rely on keys, values and each to repeatedly return the same order as each other.
A hash is an array of linked lists. A hashing function converts the key into a number which is used as the index of the array element ("bucket") into which to store the value. More than one key can hash to the same index ("collision"), a situation handled by the linked lists.
The iterator used by keys
, values
and each
returns the elements in a order consistent with their location in the hash. I imagine it iterates over the linked list in the first bucket, then over the linked list in the second bucket, etc. The points is that it doesn't randomize the order in which it iterates over the elements of the hash. That's why the docs guarantee the following:
So long as a given hash is unmodified you may rely on keys, values and each to repeatedly return the same order as each other.
What is "random"[1] is in which bucket number to which a key will hash. Each hash has a random secret number that perturbs the hashing function. This causes the order of the elements in a hash to be different for each hash and for each run of a program.[2]
Adding elements to a hash can cause the number of buckets to increase, and it can cause trigger the secret number to change (if one of the linked lists becomes abnormally long). Both of these will change the order of the elements in that 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With