#!/Perl
# AIM: To check out some array code ...
###use strict;
use warnings;

print "$0 ... Hello, World...\n";

my @array1 = ();
# A scalar array can be declared, using an '@', and initialised with elements, like -
my @array2 = qw( Apple Orange Banana Pear );
# The 'qw' is a built in function to aid in writing an array. It is functionally equivalent to writing -
my @array3 = ( "Apple", "Orange", "Banana", "Pear" );
# The count of the elements in an array can be found by -
my $arrcnt = scalar @array2;
print "Count in \@array2 = $arrcnt ...\n";
# The values stored in an array may be access simply using an index.
# The following extracts the 2nd element, that is, makes $val2 to 
# contain the value 'Orange'. Note the index is zero based, and the 
# array is addressed like a scalar, that is using '$' -
my $va2 = $array2[1];
print "Value of item 2 in \@array2 is $va2 ...\n";
# The set of elements in an array can be addressed successively by the code -
print "List in \@array2 = ";
foreach my $val (@array2) {
    print $val.' ';
}
print "\n";
# Also scalar arrays can be multi-dimensional. The square brackets are used to declare these, like -
my @mdarray = (
 [ "a", "b", "c" ],
 [ "d", "e", "f" ]
 );

# In this case count would be two (2) from the code -
my $arrcnt2 = scalar @mdarray;
print "Count in \@mdarray = $arrcnt2 ...\n";
# Care must be taken in addressing elements in the multi-dimensional array, 
# to ensure all indexes are within range. The following will address the
# 'b' and 'e' members, respectively -
$e12 = $mdarray[0][1];
$e22 = $mdarray[1][1];
print "Value of item row 1, column 2 in mdarray is $e12 ...\n";
print "Value of item row 2, column 2 in mdarray is $e22 ...\n";

# to address all elements
my $cnt = 0;
print "List of elements in \@mdarray: \n";
for (my $i = 0; $i < 2; $i++) {
	for (my $j = 0; $j < 3; $j++) {
		$cnt++;
		print "$cnt [".$mdarray[$i][$j]."]\n";
	}
}
print "\n";
print "or a multi-dimensional array can be iterated with ...\n";
print "List of elements in \@mdarray: ";
foreach my $ref (@mdarray) {
	foreach my $el (@$ref) {
		print "[$el] ";
	}
}
print "\n";

##############################################################################################
# To declare a hash, use '%', and to clear the hash ...
my %hash1 = ();
# To declare a hash with elements ... I always think of it as a 'key' pointing to a 'value' ...
my %hash1 = ( 
   'key1' => 'key1 Value',
   'key2' => 'key2 Value',
   'key3' => 'key3 Value' );

# to get count of elements in a hash
my $cnt = scalar keys %hash1;
print "Got $cnt keys in \%hash1 ...\n";

# To enumerate the keys, and values, you can use the following ... 
# note the use of the scalar '$' and the curly brackets, { } ... 
# also note the order is not necessarily as declared! ...
foreach my $key (keys %hash1 ) {
   print $key.' has value ['. $hash1{$key} ."]\n";
}
# key2 has value [key2 Value]
# key1 has value [key1 Value]
# key3 has value [key3 Value]

# To establish some order, the array of keys returned by 'keys %hash1' can be sorted ...
my @arr = keys %hash1;
foreach my $key (sort @arr ) {
   print $key.' has value ['. $hash1{$key} ."]\n";
}

@ar1 = qw(a1 a3 a3);
@ar2 = qw(b1 b2 b3);
@mdar = ();
push(@mdar, [@ar1]);
push(@mdar, [@ar2]);
$cnt = scalar @mdar;
print "mdar has $cnt members ...\n";
for ($i = 0; $i < $cnt; $i++) {
	print ' cnt='.($i + 1).': '.($mdar[$i][0]).' '.($mdar[$i][1]).' '.($mdar[$i][2])."\n";
}
@mdar = ();
push(@mdar, ["a1", "a2", "a3"]);
push(@mdar, ["b1", "b2", "b3"]);
$cnt = scalar @mdar;
print "mdar has $cnt members ...\n";
for ($i = 0; $i < $cnt; $i++) {
	print ' cnt='.($i + 1).': '.($mdar[$i][0]).' '.($mdar[$i][1]).' '.($mdar[$i][2])."\n";
}

$path = 'c:\this/that\another/end';
@arr = split(/[\\\/]/, $path);
$cnt = scalar @arr;
for ($i = 0; $i < $cnt; $i++) {
	print ' cnt='.($i + 1).': '.($arr[$i])."\n";
}
@arr = split(/(\\|\/)/, $path);
$cnt = scalar @arr;
for ($i = 0; $i < $cnt; $i++) {
	print ' cnt='.($i + 1).': '.($arr[$i])."\n";
}

# auto-generate a set of functions
my @TTColors = qw( red green blue white );
for $name (@TTColors) {
	no strict 'refs';       # allow symbol table manipulation
    *$name = *{uc $name} = sub { "<tt class=\"$name\">@_</tt>"; }
}

print "Colours\n"; # output the colours
foreach $name (@TTColors) {
	my $func = \&$name; ## get the function - the auto-generated sub
	$txt = $func->($name); # surround/encase the text
	print "[";
	print $txt;
	print "]";
	print "\n";
}

# eof - array01.pl
