Perl One Dimensional Array Functions on Array of Hashes
Perl Two-Dimensional Structures – Part 4
Foreword: In this part of the series, I talk about the one-dimensional array functions on a Perl array-of-hashes data structure.
By: Chrysanthus Date Published: 2 Apr 2016
Introduction
Length of a Two-Dimensional Array of Hashes
The length of a one-dimensional array is obtained by assigning the array name, preceded by the @ symbol, to a variable. When you do this for a two-dimensional array-of-hashes structure, you obtain the total number of rows in the structure; and that is the length of the structure. Read and try the following program:
use strict;
my @arr;
@arr[0] = {ProductID=>1, ProductName=>"TV Set", Category=> "Entertainment", Number=>50, CostPrice=>25, SellingPrice=>30};
@arr[1] = {ProductID=>2, ProductName=>"VCD", Category=>"Entertainment", Number=>50, CostPrice=>20, SellingPrice=>25};
@arr[2] = {ProductID=>3, ProductName=>"Clothe Box", Category=>"Household", Number=>45, CostPrice=>16, SellingPrice=>21};
@arr[3] = {ProductID=>4, ProductName=>"Perfume", Category=>"Beauty", Number=>100, CostPrice=>2, SellingPrice=>3};
@arr[4] = {ProductID=>5, ProductName=>"Banana", Category=>"Fruit", Number=>125, CostPrice=>5, SellingPrice=>7};
@arr[5] = {ProductID=>6, ProductName=>"Pear", Category=>"Fruit", Number=>135, CostPrice=>3, SellingPrice=>4};
my $len = @arr;
print $len;
In the case of array-of-hashes by initialization, you use the following syntax for the array name:
@$arrayReferenceName
The following program illustrates this:
use strict;
my $aohRef = [
{ProductID=>1, ProductName=>"TV Set", Category=> "Entertainment", Number=>50, CostPrice=>25, SellingPrice=>30},
{ProductID=>2, ProductName=>"VCD", Category=>"Entertainment", Number=>50, CostPrice=>20, SellingPrice=>25},
{ProductID=>3, ProductName=>"Clothe Box", Category=>"Household", Number=>45, CostPrice=>16, SellingPrice=>21},
{ProductID=>4, ProductName=>"Perfume", Category=>"Beauty", Number=>100, CostPrice=>2, SellingPrice=>3},
{ProductID=>5, ProductName=>"Banana", Category=>"Fruit", Number=>125, CostPrice=>5, SellingPrice=>7},
{ProductID=>6, ProductName=>"Pear", Category=>"Fruit", Number=>135, CostPrice=>3, SellingPrice=>4}
];
my $len = @$aohRef;
print $len;
Slicing a 2D Array-of-hashes by Rows means obtaining a range of rows in the 2D array-of-hashes structure. To do this, you begin with the @ sign. This is followed by the name of the array; then square brackets. Inside the square brackets, you begin with the index of the start row of the range, then two dots and then the index of the end row of the range. Here, a range means consecutive rows in the array. If the number of elements (rows) in the range is small, say two, three or four, then you can type their indices in the square brackets separating them with commas and you would not need the two dots.
The return object is an array-of-hashes (the slice). The return new array-of-hashes can be assigned to a new array (of hashes) variable. Nothing is deleted in the original array. The return array is a 2D array-of-hashes and you would access it as you would access other two-dimensional array-of-hashes. Read and try the following script that illustrates this:
use strict;
my @arr;
@arr[0] = {ProductID=>1, ProductName=>"TV Set", Category=> "Entertainment", Number=>50, CostPrice=>25, SellingPrice=>30};
@arr[1] = {ProductID=>2, ProductName=>"VCD", Category=>"Entertainment", Number=>50, CostPrice=>20, SellingPrice=>25};
@arr[2] = {ProductID=>3, ProductName=>"Clothe Box", Category=>"Household", Number=>45, CostPrice=>16, SellingPrice=>21};
@arr[3] = {ProductID=>4, ProductName=>"Perfume", Category=>"Beauty", Number=>100, CostPrice=>2, SellingPrice=>3};
@arr[4] = {ProductID=>5, ProductName=>"Banana", Category=>"Fruit", Number=>125, CostPrice=>5, SellingPrice=>7};
@arr[5] = {ProductID=>6, ProductName=>"Pear", Category=>"Fruit", Number=>135, CostPrice=>3, SellingPrice=>4};
my @slicedArr = @arr[2..4];
print $slicedArr[0]{'Category'}, "\n";
print $slicedArr[1]{'Category'}, "\n";
print $slicedArr[2]{'Category'}, "\n";
Remember, index counting even with slicing indices (e.g. 2..4) begin from zero.
One-dimensional array functions can be used with two-dimensional array-of-hashes structure, row-by-row. I assume that you have been reading the tutorials in this course (see below) in the order given. If you have not been doing that, then you may have problems understanding this tutorial.
Pushing A Row
You can add a row at the end of the 2D array-of-hashes. You use the 1D push function. The row added is a 1D hash. The row argument to the function is a reference to the 1D hash, which is to be added. A reference to a named 1D hash can be got as follows:
%Ha = (one=>"aaa", two=>"bbb", three=>"ccc");
$aref = \%Ha;
The \ in front of %Ha causes the reference to be returned. A reference to an anonymous 1D hash can be got as follows:
$aref = {one=>"aaa", two=>"bbb", three=>"ccc"};
where $aref is the variable holding the reference. The curly brackets return the reference.
The syntax of the push function for adding a 1D array row at the bottom of a 2D array-of-hashes, is:
push(ARRAY, Reference);
In the following program, two rows are added to a 2D array-of-hashes, using the push function twice:
use strict;
my @arr;
@arr[0] = {ProductID=>1, ProductName=>"TV Set", Category=> "Entertainment", Number=>50, CostPrice=>25, SellingPrice=>30};
@arr[1] = {ProductID=>2, ProductName=>"VCD", Category=>"Entertainment", Number=>50, CostPrice=>20, SellingPrice=>25};
@arr[2] = {ProductID=>3, ProductName=>"Clothe Box", Category=>"Household", Number=>45, CostPrice=>16, SellingPrice=>21};
@arr[3] = {ProductID=>4, ProductName=>"Perfume", Category=>"Beauty", Number=>100, CostPrice=>2, SellingPrice=>3};
@arr[4] = {ProductID=>5, ProductName=>"Banana", Category=>"Fruit", Number=>125, CostPrice=>5, SellingPrice=>7};
@arr[5] = {ProductID=>6, ProductName=>"Pear", Category=>"Fruit", Number=>135, CostPrice=>3, SellingPrice=>4};
my %HaE = (ProductID=>7, ProductName=>"Banana", Category=>"Fruit", Number=>125, CostPrice=>5, SellingPrice=>7);
my $aref1 = \%HaE;
my $aref2 = {ProductID=>8, ProductName=>"Pear", Category=>"Fruit", Number=>135, CostPrice=>3, SellingPrice=>4};
push(@arr, $aref1);
push(@arr, $aref2);
print $arr[6]{'ProductName'}, "\n";
print $arr[7]{'ProductName'}, "\n";
The push function returns the new number of rows in the array; this number is the old number plus 1 for any push function call.
Unshifting does the opposite of pushing. It prepends a row in front of a 2D array-of-hashes, returning the new number of rows in the resulting array. The syntax is:
unshift (ARRAY, Reference);
In the following program, a row is unshifted to the beginning of a 2D array-of-hashes:
use strict;
my @arr;
@arr[0] = {ProductID=>2, ProductName=>"VCD", Category=>"Entertainment", Number=>50, CostPrice=>20, SellingPrice=>25};
@arr[1] = {ProductID=>3, ProductName=>"Clothe Box", Category=>"Household", Number=>45, CostPrice=>16, SellingPrice=>21};
@arr[2] = {ProductID=>4, ProductName=>"Perfume", Category=>"Beauty", Number=>100, CostPrice=>2, SellingPrice=>3};
@arr[3] = {ProductID=>5, ProductName=>"Banana", Category=>"Fruit", Number=>125, CostPrice=>5, SellingPrice=>7};
@arr[4] = {ProductID=>6, ProductName=>"Pear", Category=>"Fruit", Number=>135, CostPrice=>3, SellingPrice=>4};
my $aref1 = {ProductID=>1, ProductName=>"TV Set", Category=> "Entertainment", Number=>50, CostPrice=>25, SellingPrice=>30};
unshift(@arr, $aref1);
print $arr[0]{'Category'}, "\n";
print $arr[1]{'Category'}, "\n";
After the unshifting, the indexing in the array is readjusted, with the unshifted row having the index of zero. The new number of rows is the old number plus 1.
The pop function removes the last row from the array and returns the reference of the removed row, shortening the original array by one row. The syntax is,
pop (ARRAY);
In the following program the last row is popped out:
use strict;
my @arr;
@arr[0] = {ProductID=>1, ProductName=>"TV Set", Category=> "Entertainment", Number=>50, CostPrice=>25, SellingPrice=>30};
@arr[1] = {ProductID=>2, ProductName=>"VCD", Category=>"Entertainment", Number=>50, CostPrice=>20, SellingPrice=>25};
@arr[2] = {ProductID=>3, ProductName=>"Clothe Box", Category=>"Household", Number=>45, CostPrice=>16, SellingPrice=>21};
@arr[3] = {ProductID=>4, ProductName=>"Perfume", Category=>"Beauty", Number=>100, CostPrice=>2, SellingPrice=>3};
@arr[4] = {ProductID=>5, ProductName=>"Banana", Category=>"Fruit", Number=>125, CostPrice=>5, SellingPrice=>7};
@arr[5] = {ProductID=>6, ProductName=>"Pear", Category=>"Fruit", Number=>135, CostPrice=>3, SellingPrice=>4};
my $oldArrayLength = @arr;
print $oldArrayLength, "\n";
my $poppedArrRef = pop(@arr);
print $$poppedArrRef{'ProductName'}, "\n";
my $newArrayLength = @arr;
print $newArrayLength, "\n";
Do read and try all the code samples of this tutorial.
Shifting a Row
The shift function does the opposite of the pop function. It removes the first row from the array and returns the reference of the removed row, shortening the original array by one row. The syntax is,
shift (ARRAY);
In the following program the first row is shifted out:
use strict;
my @arr;
@arr[0] = {ProductID=>1, ProductName=>"TV Set", Category=> "Entertainment", Number=>50, CostPrice=>25, SellingPrice=>30};
@arr[1] = {ProductID=>2, ProductName=>"VCD", Category=>"Entertainment", Number=>50, CostPrice=>20, SellingPrice=>25};
@arr[2] = {ProductID=>3, ProductName=>"Clothe Box", Category=>"Household", Number=>45, CostPrice=>16, SellingPrice=>21};
@arr[3] = {ProductID=>4, ProductName=>"Perfume", Category=>"Beauty", Number=>100, CostPrice=>2, SellingPrice=>3};
@arr[4] = {ProductID=>5, ProductName=>"Banana", Category=>"Fruit", Number=>125, CostPrice=>5, SellingPrice=>7};
@arr[5] = {ProductID=>6, ProductName=>"Pear", Category=>"Fruit", Number=>135, CostPrice=>3, SellingPrice=>4};
my $oldArrayLength = @arr;
print $oldArrayLength, "\n";
my $shiftedArrRef = shift(@arr);
print $$shiftedArrRef{'ProductName'}, "\n";
my $newArrayLength = @arr;
print $newArrayLength, "\n";
The splice function removes a portion (range) of rows from the array and replaces it with that of some other 2D array-of-hashes; if that is present. The resulting array may be longer or shorter than the original array depending on how many rows are in the replacement 2D Array-of-Hashes. If there is no replacement array-of-hashes, then the resulting array is shorter. The splice function returns the 2D array-of-hashes of the elements removed. The syntax is,
splice (ARRAY, OFFSET, LENGTH, REPLACEMENTARRAY)
ARRAY is the name of the original array. OFFSET is the index at which the removal will start. Remember, index counting begins from zero. LENGTH is the number of consecutive rows to be removed. REPLACEMENTARRAY, if present has the rows to replace the ones removed.
For our example, imagine that you want to remove 3 rows beginning from index 2 (which is position 3) and replace them with the following array:
my @arrReplace;
@arrReplace[0] = {ProductID=>7, ProductName=>"Banana", Category=>"Fruit", Number=>125, CostPrice=>5, SellingPrice=>7};
@arrReplace[1] = {ProductID=>8, ProductName=>"Pear", Category=>"Fruit", Number=>135, CostPrice=>3, SellingPrice=>4};
@arrReplace[2] = {ProductID=>9, ProductName=>"Clothe Box", Category=>"Household", Number=>35, CostPrice=>20, SellingPrice=>15};
The splice function would be,
splice (@arr, 2, 3, @arrReplace);
So, 3 rows will be removed beginning from index 2. The variable, LENGTH is 3. It happens that the number of rows replacing, is still 3.
The following program illustrates this:
use strict;
my @arr;
@arr[0] = {ProductID=>1, ProductName=>"TV Set", Category=> "Entertainment", Number=>50, CostPrice=>25, SellingPrice=>30};
@arr[1] = {ProductID=>2, ProductName=>"VCD", Category=>"Entertainment", Number=>50, CostPrice=>20, SellingPrice=>25};
@arr[2] = {ProductID=>3, ProductName=>"Clothe Box", Category=>"Household", Number=>45, CostPrice=>16, SellingPrice=>21};
@arr[3] = {ProductID=>4, ProductName=>"Perfume", Category=>"Beauty", Number=>100, CostPrice=>2, SellingPrice=>3};
@arr[4] = {ProductID=>5, ProductName=>"Banana", Category=>"Fruit", Number=>125, CostPrice=>5, SellingPrice=>7};
@arr[5] = {ProductID=>6, ProductName=>"Pear", Category=>"Fruit", Number=>135, CostPrice=>3, SellingPrice=>4};
my @arrReplace;
@arrReplace[0] = {ProductID=>7, ProductName=>"Banana", Category=>"Fruit", Number=>120, CostPrice=>5, SellingPrice=>7};
@arrReplace[1] = {ProductID=>8, ProductName=>"Pear", Category=>"Fruit", Number=>135, CostPrice=>3, SellingPrice=>4};
@arrReplace[2] = {ProductID=>9, ProductName=>"Clothe Box", Category=>"Household", Number=>35, CostPrice=>20, SellingPrice=>15};
my @removedArr = splice (@arr, 2, 3, @arrReplace);
for (my $i=0; $i<@arr; ++$i)
{
foreach my $var (@arr[$i])
{
print $arr[$i]{'ProductID'}, ', ';
print $arr[$i]{'ProductName'}, ', ';
print $arr[$i]{'Category'}, ', ';
print $arr[$i]{'Number'}, ', ';
print $arr[$i]{'CostPrice'}, ', ';
print $arr[$i]{'SellingPrice'}, ', ';
}
print "\n";
}
print "\n";
for (my $i=0; $i<@removedArr; ++$i)
{
foreach my $var (@removedArr[$i])
{
print $removedArr[$i]{'ProductID'}, ', ';
print $removedArr[$i]{'ProductName'}, ', ';
print $removedArr[$i]{'Category'}, ', ';
print $removedArr[$i]{'Number'}, ', ';
print $removedArr[$i]{'CostPrice'}, ', ';
print $removedArr[$i]{'SellingPrice'}, ', ';
}
print "\n";
}
Do not forget to read and try the code.
End of Tutorial and end of Series
This is the end of the tutorial and the end of the series. I hope you appreciated the series.
Chrys
Related Links
Perl BasicsPerl Data Types
Perl Syntax
Perl References Optimized
Handling Files and Directories in Perl
Perl Function
Perl Package
Perl Object Oriented Programming
Perl Regular Expressions
Perl Operators
Perl Core Number Basics and Testing
Commonly Used Perl Predefined Functions
Line Oriented Operator and Here-doc
Handling Strings in Perl
Using Perl Arrays
Using Perl Hashes
Perl Multi-Dimensional Array
Date and Time in Perl
Perl Scoping
Namespace in Perl
Perl Eval Function
Writing a Perl Command Line Tool
Perl Insecurities and Prevention
Sending Email with Perl
Advanced Course
Miscellaneous Features in Perl
Perl Two-Dimensional Structures
Advanced Perl Regular Expressions
Designing and Using a Perl Module
More Related Links
Perl Mailsend
PurePerl MySQL API
Perl Course - Professional and Advanced
Major in Website Design
Web Development Course
Producing a Pure Perl Library
MySQL Course
BACK