sandy_1028 has asked for the wisdom of the Perl Monks concerning the following question:
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: hash and arrays
by ccn (Vicar) on Nov 08, 2008 at 11:28 UTC | |
It is often more readable to use the => operator between key/value pairs. The => operator is mostly just a more visually distinctive synonym for a comma, but it also arranges for its left-hand operand to be interpreted as a string -- if it's a bareword that would be a legal simple identifier (=> doesn't quote compound identifiers, that contain double colons). This makes it nice for initializing hashes. perldoc perldata | [reply] [d/l] [select] |
|
Re: hash and arrays
by gone2015 (Deacon) on Nov 09, 2008 at 00:27 UTC | |
With apologies if a brief tutorial was not what you wanted... When to use Hash and Arrays in the program ? Arrays and Hashes are similar in that they are containers for multiple things (scalars), and you access those things using a form of key. In the case of an Array the key (usually called an index) is an integer -- so $foo[25] is item 25 in the array @foo. In the case of a Hash the key is a string -- so $bar{'homburg'} is the homburg item in the hash %bar. Arrays have an implied ordering: item 0 comes before item 1 and so on. The contents of an array may be treated as a list. Hashes have no ordering whatsover. So when keys(%bar) gives you a list of all the keys in the hash, they are in no predictable order -- in particular, not in the order things were put into the hash (except by pure chance) -- this is a common trap that people fall into. Arrays are used where your key values are simple integers (in a reasonable range), or as containers for lists. For example, the array @days = ('Mon', 'Tue', 'Wed', 'Thurs', 'Fri', 'Sat', 'Sun') can be accessed by index: $days[4] gives 'Fri', day 4 of the week, where day 0 is 'Mon'. Or treated as a list: foreach my $d (@days) sets $d to each day name in turn, from 'Mon' to 'Sun'. Hashes are used where your keys are arbitrary -- noting that the keys you use are converted to strings. For example, the hash %day_num = ('Mon' => 0, 'Tue' => 1, 'Wed' => 2, 'Thu' => 3, 'Thurs' => 3, 'Fri' => 4, 'Sat' => 5, 'Sun' => 6) can be accessed by the name of a day to get the day number: $day_num{'Thurs'} gives 3. Note that $day_num{'sat'} will give undef, because there is no such entry -- hashes are very literal minded about the keys. The function exists will tell you whether a given key exists in the hash, so exists($day_num{'sat'}) would return false, in this case. Other essential functions for using hashes are keys, values and each. You will also find sort used quite a bit with keys, to impose order on chaos. You can use a Hash to implement a sparse array. So, $sa{79}, $sa{200000}, $sa{123456} could be entries an a sparse array. Noting that the absent entries would all appear as undef. Hash keys are strings, but if you use a number, as above, it will be converted to a string -- Perl is broadminded, and generally does not discriminate between string and numeric values (which has its own little quirks, but that's another story). This is a big topic. I recommend a little reading ! In which scenario => is used? As others have said, broadly speaking there is no difference between '=>' and ',' apart from the appearance. I used '=>' between each key and its value in the "literal hash" above. I could just as well have used ',', but the '=>' makes the key/value pairs more obvious. However, that is not the whole story. Perl has the notion of a "bareword", whose genesis is lost in the mists of time. A bareword is simply a thing that looks like an identifier with no "sigil" (leading '$', '@', '%', ... etc) and no trailing '(). Deciding what a bareword means is a bit of a problem for Perl. If it knows of a subroutine which is defined to take no arguments, Perl will (generally) treat a bareword as a call of that subroutine -- this is how "constants" (as defined by use constant) are implemented. Otherwise Perl either has to know what to do, or must guess. If you use strict (and, frankly, you need a good reason not to), Perl will throw a compile time error rather than guess at the meaning of a bareword. There are cases where Perl knows what to do with barewords, and hashes are a prime example: The relationship between "constants" and barewords is slightly tricky. Consider: whose output is:
homburg, homburg!, HA, Ha!, HOMBURG, HomBurg!
$k = HOMBURG -> $k=HA
$bar{homburg}=homburg!, $bar{HOMBURG}=HomBurg!, $bar{$k}=Ha!, $bar{+HOMBURG}=Ha!
which shows a number of things:
If you're still awake, you may be asking yourself why +HOMBURG doesn't generate an error, given that the value of HOMBURG is manifestly not numeric. (The clever people who know the answer to this one can leave now.) So:
Finally, while on the topic of quirks in Perl's handling of strings... when evaluated as a boolean (true/false) value an empty string is false and a non-empty string is considered true, except for '0'. Note that this is not treating the string as a number -- to be false a non-empty string must be exactly one character long, and that character must be '0' ! So: gives:
'0' is False and == 0
'0000' is True and == 0
'+0' is True and == 0
'-0' is True and == 0
' 0' is True and == 0
'0 ' is True and == 0
'0E0' is True and == 0
You will often see code which tests strings thus: if ($string). This is shorter than if ($string ne ''), and has the advantage of working if $string is undef. If $string can ever be '0', however, you will regret not having written if (defined($string) && ($string ne '')), clumsy though that may appear !
| [reply] [d/l] [select] |
|
Re: hash and arrays
by jwkrahn (Abbot) on Nov 08, 2008 at 11:29 UTC | |
Any time you use , you can use => instead. | [reply] [d/l] [select] |
|
Re: hash and arrays
by apl (Monsignor) on Nov 08, 2008 at 12:58 UTC | |
| [reply] |
by jwkrahn (Abbot) on Nov 09, 2008 at 15:53 UTC | |
That should be Programming Perl. (See: What's the difference between "perl" and "Perl"?) Or are you suggesting that sandy_1028 buy the first edition, which is out of print, because Randal is no longer a co-author of that particular book. | [reply] |
by apl (Monsignor) on Nov 10, 2008 at 11:28 UTC | |
| [reply] |
|
Re: hash and arrays
by zentara (Cardinal) on Nov 08, 2008 at 18:41 UTC | |
It is often desired to retreive the data by a name, instead of a number, so hashes are used. They are often called linked-lists in c. There are 2 lists, the keys and the values, so you can access data with $hash{$key_name}. Hashes are very convenient, but are slower. That is it in a nutshell. I'm not really a human, but I play one on earth Remember How Lucky You Are | [reply] [d/l] |
by ikegami (Patriarch) on Nov 08, 2008 at 19:44 UTC | |
Hashes aren't linked lists. Not even close. Hashes are completely different than linked lists. A hash is an array of vectors of key-value pairs. The array is indexed by a hash of the key. Hash functions return a as-unique-as-possible number for a string, but always the same number for equivalent strings. The array grows as elements are added to the hash. This keeps the vectors very short if an appropriate hashing algorithm is used. The vectors could very well be implemented as linked lists, but each list contains only the elements that hash to the same bucket (array element). Hashes are much more efficient than linked lists. Since the first step to add, delete or fetch an element from the data structure is to locate the element in the data structure, let's consider how long that takes. With a linked list, every key needs to be compared against the searched key if the element is absent ( O(N)* ), or half that on average if the element is present ( Avg case O(N)* ). With a hash, only the keys that hash to the same bucket are compared. With a properly working hashing algorithm, that should be a tiny number no matter how many elements are in the data structure. ( Avg case O(1)* ) * — Treats the keys length as bounded, as usual. | [reply] [d/l] [select] |
|
Re: hash and arrays
by JadeNB (Chaplain) on Nov 10, 2008 at 00:31 UTC | |
=> is used when you want to compute a minimum; as, for example, [ $a => $b ]->[ $b <= $a ]. | [reply] [d/l] [select] |
by repellent (Priest) on Nov 11, 2008 at 08:13 UTC | |
as it relies on too much syntax magic. The first set of brackets [ ] is used to indicate an anonymous array, whereas the second set of brackets ->[ ] de-references the array. => is used as a fat comma (not greater-than-or-equal-to), whereas <= is used as less-than-or-equal-to. Hence,
| [reply] [d/l] [select] |