Say you have an array @a = qw/ a b c d/;
and a hash %a = ('a' => 1, 'b' => 1, 'c' => 1, 'd' => 1);
Is there any situation where creating the array version is better than creating the hash (other than when you have to iterate over all the values as in something like
for (@a){
....
in which case you would have to use keys %a
if you went with the hash)? Because testing whether a specific value is in a hash is always more efficient than doing so in an array, correct?
In Perl an
@array
is an ordered list of values($v1, $v2, ...)
accessed by an integer (both positive and negative), while a %hash is an unordered list of 'key => value' pairs(k1 => $v1, k2 => $v2, ...)
accessed by a string.There are modules on CPAN that implement ordered hashes, like: Hash::Ordered and Tie::IxHash
You might want to use an array when you have ordered 'items' presumably a great number as well, for which using a %hash and sorting the keys and/or the values would be inefficient.
Arrays are ordered lists of values. They can contain duplicate values.
Hashes are a mapping between a key (which must be unique) and a value (which can be duplicated). Hashes are (effectively) unordered, which means that keys come out in apparently random order rather than the order in which they are entered.
Hashes can also be used as sets when only the key matters. Sets are unordered and contain only unique "values" (the hash's keys).
Which one to use depends on your data and algorithm. Use an array when order matters (particularly if you can't sort to derive the order) or if duplicate values are possible. Use a set (i.e. use a hash as a set) when values must be unique and don't care about order. Use a hash when uniqueness matters, order doesn't (or is easily sortable), and look-ups are based on arbitrary values rather than integers.
You can combine arrays and hashes (via references) to create arbitrarily complex data structures.
This about using numbers as hash keys. It doesn't answer the question directly as it doesn't compare the facilities that arrays provide, but I thought it would be a good place to put the information.
Suppose a hash with ten elements is built using code like this
and then we query it, looking for keys that are powers of ten. Of course the easiest way to multiply an integer by ten is to add a zero, so it is fine to write
which has the output
We entered ten elements but this shows only six. What has happened? Let's take a look at what's in the hash.
and this outputs
so the hash doesn't use the keys that we imagined. It stringifies the numbers in a way that it would be foolish to try to emulate.
For a slightly more practical example, say we had some circles and wanted to collect into sets by area. The obvious thing is to use the area as a hash key, like this program which creates 100,000 circles with random integer diameters up to 18 million.
Now let's see how many of those hash keys use scientific notation
which says (randomly, of course)
so there really isn't a tidy way of know what string perl will use if we specify a number as a hash index.
There are many emergent properties. Primarily,