Broad Network


Perl Predefined Functions for List Data

Using Perl Arrays – Part 1

Perl Course

Foreword: In this part of the series, I talk about Perl predefined functions for list data.

By: Chrysanthus Date Published: 30 Oct 2015

Introduction

This is part 1 of my series, Using Perl Arrays. In this part of the series, I talk about Perl predefined functions for list data.

Pre-Knowledge
This series is part of the volume, Perl Course. At the bottom of this page, you will find links to different series you should have read before coming here.

The grep Function
There are two syntaxes for the grep() function. One is,

    grep EXPR,LIST

and the other is,

    grep BLOCK LIST

We look at the first syntax first. Consider the following code, which prints out any word that is alphabetically less than the word, “fruit” – dictionary-wise:

use strict;

    sub fn
        {
            my @arr = ("orange", "apple", "lime", "lemon", "grape", "banana", "pineapple");

            foreach (@arr)
                {
                    if ($_ lt "fruit")
                        {
                            print $_, "\n";
                        }
                }
        }

    fn();

The output is:

apple
banana

The code has a function. In the function, you have an array, a foreach-loop and an if-condition. The condition or expression is, ($_ lt "fruit"). This function actually returns a list of values from the total list in the array, if the condition (expression) is true. The condition or expression is tested on each value in the array.

The above code, can be rewritten in a shorter way using the grep() function as follows:

use strict;

    my @arr = ("orange", "apple", "lime", "lemon", "grape", "banana", "pineapple");

    my @arrRet = grep($_ lt "fruit", @arr);

    print $_, "\n" foreach @arrRet;

The grep function has returned the values in the array for which the expression evaluates to true. The first argument to the grep function is the expression and the second argument is the array. Note that this second code with the grep function is shorter and more mature.

The expression can be a regular expression. Consider the following code:

use strict;

    sub fn
        {
            my @arr = ("orange", "apple", "lime", "lemon", "grape", "banana", "pineapple");

            foreach (@arr)
                {
                    if ($_ =~ /^apple|banana$/)
                        {
                            print $_, "\n";
                        }
                }
        }

    fn();

The output is:

apple
banana

The condition or expression is ($_ =~ /^apple|banana$/) . In order to shorten this code using the grep function, you will use just the regular expression without the preceding “$_ =~” as follows:

use strict;

    my @arr = ("orange", "apple", "lime", "lemon", "grape", "banana", "pineapple");

    my @arrRet = grep(/^apple|banana$/, @arr);

    print $_, "\n" foreach @arrRet;

Let us now address the second syntax. If the test is elaborate, then place the elaborated test in a block. The following code uses an anonymous block of two statements for the test:

use strict;

    sub fn
        {
            my @arr = ("orange", "apple", "lime", "lemon", "grape", "banana", "pineapple");

            foreach (@arr)
                {
                    {
                        print $_, "\n" if $_ eq "apple";
                        print $_, "\n" if $_ eq "banana";
                    }
                }
        }

    fn();

The output is:

apple
banana

This code can be shortened using the grep function as follows:

use strict;

    my @arr = ("orange", "apple", "lime", "lemon", "grape", "banana", "pineapple");

    my @arrRet = grep(
                        {
                            /^apple|banana$/;
                        }
                     @arr);

    print $_, "\n" foreach @arrRet;

The output is:

apple
banana

Note: when using a block as the first argument to the grep function, you have to omit the comma that separates the two arguments in the grep function.

The syntaxes for the grep() function again are:

    grep EXPR,LIST

    grep BLOCK LIST

The function evaluates the EXPR or BLOCK for each element of LIST (locally setting $_ to each element) and returns the list value consisting of those elements for which the expression evaluated to true – that is list context. In scalar context, it returns the number of times the expression was true.

With the grep function, the original array remains unchanged.

The map Function
The syntaxes for the map() function are:

    map EXPR,LIST

    map BLOCK LIST

The map() function is similar to the grep function in the sense that it acts on the elements of an array. Actually, it uses EXP or BLOCK to act on each element of the array. It can modify each element of the array to a new value or the same value or undef. It returns the modified sub list. The original array may or may not be changed. Try the following code, where a fruit name is double if the name is alphabetically less than the word, “fruit”.

use strict;

    my @arr = ("orange", "apple", "lime", "lemon", "grape", "banana", "pineapple");

    my @arrRet = map($_ lt "fruit" ? $_.=" $_" : undef, @arr);

    print $_, "\n" foreach @arrRet;
    print @arr;

The first map() syntax has been used. The output is:

apple apple



banana banana

orangeapple applelimelemongrapebanana bananapineapple

undef is not printed. In this code the original array has been changed. The original array is changed depending on EXP or BLOCK.

The map function can be used to square all the numbers in an array. Try the following code:

use strict;

    my @arr = (0, 1, 2, 3, 4, 5);

    my @arrRet = map($_ * $_, @arr);

    print $_, "\n" foreach @arrRet;
    print @arr;

The output is:

0
1
4
9
16
25
012345

The original array has not been changed in this case.

Square means multiply a quantity by itself as in, $ * $_. The first syntax has been used in the above code. If EXP was $_ = $_ *  $_, then the original array would have been changed to the squares of the numbers.

In scalar context, the map function returns the total number of elements generated.

The join Function
The syntax for this function is:

join EXPR,LIST

It joins a list of values into a string, using EXP as the separator, and returns the string. The statement,

    my $str = join(', ', "orange", "apple", "lime", "lemon");

produces the string,

    "orange, apple, lime, lemon"

In the statement, the separator is ', '. When there is no ambiguity, a list as in the second argument above, does not have to be in parentheses.

The qw/STRING/ Function
This function (operator) returns a list, which can be received by an array. It separates a string of words into a list of the words and returns the list. It uses whitespace between the words to separate the words. Try the following code:

use strict;

    my @arr = qw/one two three/;

    print $_, "\n" foreach @arr;

The output is:

    one
    two
    three

The forward slashes can be replaced by double or single quotes to have

    qw"one two three"

or

    qw'one two three'

The reverse Function
The syntax for the reverse function is:

    reverse LIST

If the argument is a string scalar variable, the characters are reversed and returned. The original string remains unchanged. Read and try the following code:

use strict;

    my $str = "a b c d e";
    my $ret = reverse($str);
    print $ret, "\n";
    print $str, "\n";

The output is:

e d c b a
a b c d e

If the argument to the function is an array (list) of strings, and receiving variable is a scalar, then each element is reversed and the order of the elements are also reversed. The original array remains unchanged. Read and try the following code:

use strict;

    my @arr = ("one", "two", "three");
    my $ret = reverse(@arr);
    print $ret, "\n";
    print @arr, "\n";

The output is:

    eerhtowteno
    onetwothree

The above situations are scalar context (receiving variable, $ret is scalar).  In list context, the order in which the elements were, is reversed but each element is not reversed. The original array remains unchanged. Read and try the following code:

use strict;

    my @arr = ("one", "two", "three");
    my @arrRet = reverse(@arr);
    print @arrRet, "\n";
    print @arr, "\n";

The output is:

   threetwoone
   onetwothree

The sort Function
The syntaxes are:

    sort SUBNAME LIST

    sort BLOCK LIST

    sort LIST

In list context, this sorts the LIST and returns the sorted list value. In scalar context, the behavior of sort() is undefined.

If SUBNAME or BLOCK is omitted, sorts in standard string comparison order (0-9A-Za-z). Try the following code:

use strict;

    my @arr = ('one', '2two', 'three', 'four', 'five');

    my @newArr = sort(@arr);

    print "$_ " foreach @newArr;

The output is:

    2two five four one three

The original array remains unchanged, everything being equal. I will come back to this function in a different part of a different series, in the volume.

That is it for this part of the series.

Chrys

Related Links

Perl Basics
Perl 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

NEXT

Comments

Become the Writer's Fan
Send the Writer a Message