Syntactic Confectionery Delight PerlMonks

### Arrays and hashes only with references

by grizzley (Chaplain)
 on Mar 14, 2008 at 13:50 UTC Need Help??

I am teaching right now a friend, who wants a new job, and just yesterday thought about how to explain array of arrays or hash of hashes etc. Here is how I tried:

For a little bit forget about array (@) and hash (%) notation. Stick only to variable (\$) or in other words, reference symbol and see how easy (I hope) it is.

Always when you want hash, use curly brackets {}, always if array - square brackets []. And on one nesting level treat everything as list of scalars, nothing more, nothing less.

```\$arrayref = [1, 3, 5, 7];
\$hashref = {key1=>val1, key2=>val2, key3=>val3};

When you need some value from hash or array, do following:

```# want array element - use square brackets
\$value = \$\$arrayref[2];
# want hash element - use curly brackets
\$othervalue = \$\$hashref{key2};

Lets build more complicated structure. The first rule: don't use any reference more than once while building another structure. Second rule: treat reference as normal scalar value.

```# array of arrays

# array - square brackets. Created three times, remember, every refere
+nce can be used only once to build another structure.
\$arrayref1 = [1, 3, 5, 7];
\$arrayref2 = [1, 3, 5, 7];
\$arrayref3 = [1, 3, 5, 7];
# array of arrays - again: array = square brackets, and it is still on
+ly list of scalars, nothing more
\$array_of_arrays = [\$arrayref1, \$arrayref2, \$arrayref3];
# see how it looks (notice, that Dumper operates only on references. W
+hat kind of brackets do you see in the dump?):
use Data::Dumper;
print Dumper \$array_of_arrays;

# now: get one element. We have three elements in hmm, lets say, 'oute
+r' level, so the last one will be(array-square brackets):
\$\$array_of_arrays[2].....
# and there are 4 values in 'inner' level, so lets take last one:
\$value = \$\$array_of_arrays[2][3];

Easy, isn't it? Now with hashes, similarly, only other brackets:

```# hash of hashes

# hash - curly brackets
\$hashref1 = {key1 => value1, key2 => value2, key3 => value3, key4 => v
+alue4};
\$hashref2 = {key1 => value1, key2 => value2, key3 => value3, key4 => v
+alue4};
\$hashref3 = {key1 => value1, key2 => value2, key3 => value3, key4 => v
+alue4};

# hash of hashes, which brackets? :)
\$hash_of_hashes = {key11 => \$hashref1, key22 => \$hashref2, key33 => \$h
+ashref3};

# see how it looks:
use Data::Dumper;
print Dumper \$hash_of_hashes;

# get an element. Nothing surprising, starting from 'outer' level:
\$\$hash_of_hashes{key22}.........
# and end with 'inner' key
\$\$hash_of_hashes{key22}{key4};

That's it. Easy? I think so. Lets mix the structures. The rules stay the same: use every reference only once, treat reference as a scalar, curly brackets = hash, square brackets = array.

```\$monk1 = 'Jack';
\$monk2 = 'John';
\$monk3 = 'Mark';
\$monk4 = 'Rudolf';

#order of monks important - using array - square brackets
\$bank_left1 = [\$monk1, '', \$monk2];
\$bank_left2 = [];
\$bank_left3 = [];
\$bank_left4 = [];
# order of banks important - use array
\$left_nave = [\$bank_left1, \$bank_left2, \$bank_left3, \$bank_left4];

\$bank_right1 = [];
\$bank_right2 = [\$monk3];
\$bank_right3 = [];
\$bank_right4 = [];
\$right_nave = [\$bank_right1, \$bank_right2, \$bank_right3, \$bank_right4]
+;

# existence of elements is important, order not - lets do hash
\$church = {'left nave'=>\$left_nave, 'right nave'=>\$right_nave, 'altar'
+=>1, 'tabernacle'=>1};

# lets declare hash of arrays at once, order of plants not important,
+but array is here more convenient.
# See, instead of (key, value) pairs I use (key, reference-to-array).
\$garden = {'plants'=>['potato', 'carrot', 'apple tree'], 'monks'=>[\$mo
+nk4], 'rain'=>1};

# and finally whole monastery, not rich, but its our home :)
\$monastery = {'church'=>\$church, 'garden'=>\$garden};

# see how it looks and where monks reside:
use Data::Dumper;
print Dumper \$monastery;

Now is time to go back to @ and %. Rules are simple: if you have reference \$arrayref to an array and need to use it as array, just write @\$arrayref. Similarly use \$hashref as %hashref if some function needs hash. Two simple examples:

```# using @ in join function
\$arrayref = \$\$monastery{'garden'}{'plants'};
print "Plants: ", join ", ", @{\$arrayref}; # or @\$arrayref
# or just
# print "Plants: ", join ", ", @{\$\$monastery{'garden'}{'plants'}};

# using % in keys function
\$hashref_churchelems = \$\$monastery{'church'};
print "\nChurch elements: ", join ", ", keys %{\$hashref_churchelems};
# or just
# print "\nChurch elements: ", join ", ", keys %{\$\$monastery{'church'}
+};
print"\n";

# monk sitting in church -> in left nave -> in first bank -> as first
print "Monk: ", \$\$monastery{'church'}{'left nave'}[0][0], "\n";

That's how structures look from ref point of view.

Replies are listed 'Best First'.
Re: Arrays and hashes only with references
by wade (Pilgrim) on Mar 14, 2008 at 17:16 UTC
I code similarly to this but instead of:
```\$value = \$\$arrayref[2];
I prefer:
```\$value = \$arrayref->[2];
The beauty of that notation is that it doesn't treat the outer level of a nest any differently.
Re: Arrays and hashes only with references
by Pancho (Pilgrim) on Mar 14, 2008 at 20:52 UTC

Big ++ on this tutorial, since it is (a) brief and to the point, (b) step by step, (c) includes code to download and tinker with. Just what a noob (i.e. me) needs. Beggars can't be choosers but adding the alternate syntax (which Wade illustrated) would make it even better.

Grizzley Keep 'em coming. Thanks

Pancho
Re: Arrays and hashes only with references
by hsinclai (Deacon) on Sep 19, 2008 at 02:19 UTC
++ on your posting grizzley - this has gotten me over a huge hump !

-Harold

Create A New User
Node Status?
node history
Node Type: perltutorial [id://674203]
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (3)
As of 2017-11-18 05:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
In order to be able to say "I know Perl", you must have:

Results (277 votes). Check out past polls.

Notices?