Perl Arrays as Sets
Using Perl Arrays – Part 5
Perl Course
Foreword: In this part of the series I talk about the equality of two arrays, the intersection of two arrays, the union of two arrays and the difference between two arrays.
By: Chrysanthus Date Published: 30 Oct 2015
Introduction
Equality of Two Arrays
Two arrays are equal if they have the same elements in the same order. To test whether arrays are equal, use the smart match operator, ~~ . You can type the two array names with the ~~ operator in an if-condition. Try the following code:
use strict;
use List::Util 'shuffle';
my @fruits = ("pear", "orange", "banana", "pineapple", "lime", "apple", "lemon");
my @plants = ("pear", "orange", "banana", "pineapple", "lime", "apple", "lemon");
if (@fruits ~~ @plants)
{
print "Arrays are equal.";
}
else
{
print "Arrays are different.";
}
The output is:
Arrays are equal.
If you change the order of any of the elements, you will have "Arrays are different." .
We now know two uses of the ~~ operator. It can be used to check if an item is in an array and it can also be used to check if two arrays are equal.
Consider two arrays, @A and @B. The union of two arrays are all the elements in @A and @B without repetition. The intersection of two arrays are the elements that are in both @A and @B. In this tutorial the difference of two arrays are elements that are in @A and @B but not in both. You can use one code to determine the union, intersection and difference. Read and try the following code that illustrates this (explanation is given below).
use strict;
my @A = ("pear", "orange", "banana", "pineapple");
my @B = ("pear", "orange", "lime", "lemon", "apple");
my (@union, @intersection, @difference);
my %count = ();
foreach my $element (@A, @B)
{
$count{$element}++;
}
foreach my $element (keys %count)
{
push @union, $element;
push @{ $count{$element} > 1 ? \@intersection : \@difference }, $element;
}
print "$_ " foreach @union; print "\n";
print "$_ " foreach @intersection; print "\n";
print "$_ " foreach @difference; print "\n";
The output is:
orange pineapple banana pear apple lime lemon
orange pear
pineapple banana apple lime lemon
The first line of the output is for the union. The second line is for the intersection and the third line is for the difference.
I now explain the code: The first code segment has the arrays. The statement after that declares the arrays that will hold the results. Then you have the empty hash, %count defined.
You then have a foreach loop. The list for this foreach loop are all the elements of the arrays, including repetitions. Inside the foreach loop, you have:
$count{$element}++;
You should have seen something like this before, in this series. This statement accesses the next key/value pair of the %count hash; by so doing it writes a key/value pair, where $element from the foreach list is the key. A hash will never allow more than one key of the same value. So, if a key is recorded into the hash for the first time, the corresponding value is given by the statement as 1. If the key is recorded (overridden) for the second time, the corresponding value is 2. If the key is recorded into the hash for the third time, the corresponding value is 3, and so on. So, at the end of the iteration, the keys of the %count hash are the elements of all the arrays, without repetition. However, the number of occurrence of each key in all the arrays is the corresponding value (number) for the key/value pair.
push @{ $count{$element} > 1 ? \@intersection : \@difference }, $element;
Now, \@intersection is a reference. To dereference it, you need @{\@intersection}. \@difference is also a reference. To dereference it you need, @{\@difference}.
This second statement is a push statement, which pushes a key ($element) of the %count hash into an array, its first argument. The question is, what array. Inside the curly brackets of this array in question, you have the conditional (contracted) if-construct, which is:
$count{$element} > 1 ? \@intersection : \@difference
Realize at this point that Perl can have a statement within such curly brackets. If the condition ($count{$element} > 1) is true, the dereferenced \@intersection becomes the array in question. If the condition is false, the dereferenced \@difference becomes the array in question. So the question of what array, has been answered.
The elements of the union of arrays, are sent to the @union array, one after the other. If an element is an intersection element, it goes into the @intersection array of the second push statement. If an element is a difference element, it goes into the @difference array of the second push statement.
The above code first obtains the union of arrays, whose elements are sent to the @union array. Then each element of the union of arrays is sent either to the @intersection array or to the @difference array.
That is it for this part of 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