[WpProQuiz 3]
[WpProQuiz_toplist 3]
Perl quiz on Operators
Learning through sharing
What is chomp and chop?
chomp()
The chomp() function will remove (usually) any new line character from the end of a string. The reason we say usually is that it actually removes any character that matches the current value of $/ (the input record separator), and $/ defaults to a new line. It returns the total number of characters removed from all its arguments and If VARIABLE is omitted, it chomps $_
So, if $/ =”\t” then chomp would remove every tab instead of new line.
For more information on the $/ variable, try perldoc perlvar and see the entry for $/ and perldoc -f chomp
Note: if chomp doesn’t behave as it should by default, hint is to check record separator ($/)
chop()
Sometimes you will find you want to unconditionally remove the last character from a string. While you can easily do this with regular expressions, chop is more efficient. Check perldoc -f chop
The chop() function will remove the last character of a string (or group of strings) regardless of what that character is and return the last character chopped. In case of array it return the last character chopped of the last element of the array. Note, if you want to easily remove newlines or line separators see the chomp().
As chop return the last character chopped of the string , if you want it's reverse i.e. return all characters except the last from the string you could use substr($string, 0, -1)
Chomp and chop, both functions can be applied on strings,array,hash. We would see it by three examples for each functions.
Example 1. Chomping a string
Most often you will use chomp() when reading data from a file or from a user. When reading user input from the standard input stream (STDIN) for instance, you get a newline character with each line of data. chomp() is really useful in this case because you do not need to write a regular expression and you do not need to worry about it removing needed characters.
When running the example below, using the enter key on a line by itself will exit the program.
[perl]#!/usr/bin/perl
use strict;
use warnings;
my $username = <STDIN>;
print "before chomp: $username";
chomp $username; #or chomp($username); or chomp (my $username =<STDIN>); in one line
print "After chomp: $username";[/perl]
Output:
[vim][Sanjeev@Alien Coders]$ perl chomp_examples.pl
Alien Coders
before chomp: Alien Coders
After chomp: Alien Coders[Sanjeev@Alien Coders]$[/vim]
First print got printed with new line which you entered while typing. Yes, it took new line (pressed enter) also as user input. Second line removed that new line, so second print is displayed along with shell on the same line.
Example 2. Chomping an array
If you chomp an array, it will remove newline from the end of every element in the array:
[perl] #!/usr/bin/perl
use strict;
use warnings;
my @array = ("sanjeev\n", "Jassi", "AlienCoders\n");
print "Before chomp:\n";
print "@array\n";
chomp(@array);
print "After chomp:\n";
print "@array\n";[/perl]
Output:
[vim]Before chomp:
sanjeev
Jassi AlienCoders
After chomp:
sanjeev Jassi AlienCoders[/vim]
As you can see, the newlines have been removed from "sanjeev" and "AlienCoders", but no characters have been removed from "jassi".
Example 3. Chomping a hash
If you pass a hash into chomp() function, it will remove newlines from every value (not key) of the hash. Remember key is always unique and string (internally). So, if you add new line in key then use that new line char also while using that key. Better to avoid such nasty thing:
[perl] #!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my %hash = (
'first' => "one\n",
'second' => "two\n",
'third' => "three\n",
);
print "before chomp:\n";
print Dumper(\%hash);
chomp(%hash);
print "after chomp:\n";
print Dumper(\%hash);[/perl]
Output:
[vim]before chomp:
$VAR1 = {
'first' => 'one
',
'second' => 'two
',
'third' => 'three
'
};
after chomp:
$VAR1 = {
'first' => 'one',
'second' => 'two',
'third' => 'three'
};[/vim]
It clearly shows that how new line is effective before chomp and it looks nice after chomp.
Example 4. Chopping a string
The chop() function removes and returns the last character from the given string whatever it is. So don’t do any mistake by assuming that it removed new line from the user input with its first use. When you will use it second time it will again remove one more character from user input but chomp only and only removes new line (or whatever is stored in $/).
[perl]#!/usr/bin/perl
use strict;
use warnings;
my $string = 'Perl';
my $char = chop($string); #to return the chopped character in a variable
print "String: $string\n";
print "Char: $char\n";[/perl]
Output:
[vim]String: Per
Char: l[/vim]
Example 5. Chopping an array
If you pass the chop() function to an array, it will remove the last character from every element in the array.
[perl]#!/usr/bin/perl
use strict;
use warnings;
my @arr = ('Jassi', 'Sanjeev', 'Alien Coders');
my $last_char = chop(@arr);
print "@arr\n";
print "Last Char: $last_char\n"; #it will store last character of last element in the array[/perl]
Output:
[vim]Jass Sanjee Alien Coder
Last Char: s[/vim]
Example 6. Chopping a hash
If you pass a hash into chop() function , it will remove the last character from the values (not the keys) in the hash. For example:
[perl] #!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my %hash = (
first => 'one',
second => 'two',
third => 'three',
);
print “Before chop:\n”;
print Dumper \%hash;
my $chr = chop(%hash);
print “After chop: \n”;
print Dumper(\%hash);
print "Char: $chr\n"; #it always have last character of last value in hash[/perl]
Output:
[vim]Before chop:
$VAR1 = {
'first' => 'one',
'second' => 'two',
'third' => 'three'
};
After chop:
$VAR1 = {
'first' => 'on',
'second' => 'tw',
'third' => 'thre'
};
Char: e[/vim]
Note:
Credit: http://perlmeme.org
Sorting an array and hash elements in PerlStandard string comparison means based on ASCII value of those characters. Like @arr = qw (Call all). In this case it will be sorted as Call all which was not expected. So to make it work properly we use case-insensitive sort.
If SUBNAME is specified, it gives the name of a subroutine that returns an integer less than, equal to, or greater than 0 , depending on how the elements of the list are to be ordered. (The <=> and cmp operators are extremely useful in such routines.)
Note: The values to be compared are always passed by reference and should not be modified . $a and $b are global variable and should not be declared as lexical variables.
sort() returns aliases into the original list like grep, map etc which should be usually avoided for better readability.
As sorting always does string sorting, so to do numeric sorting we need to use a special syntax which a sort {$a ó $b} LIST. We will see these conditions using Perl codes.
How reverse sorting works
Systax to use reverse sort is reverse LIST. It works on sorted LIST usually. But in scalar context, it concatenates the elements of LIST and returns a string value with all characters in the opposite order.
In scalar context if argument is not passed it will reverse the value of $_
Ex:
[perl]$_ = “dlrow ,olleH”;
print scalar reverse; #in this case print reverse would not works because it expects a LIST
[/perl]
Try this out:
[perl]
my @arr1 = qw(1 two 3 0 4 Two 5 six 7 8 9 ten);
my @arr2 = sort {$a cmp $b} @arr1;
print “\n@arr2\n”;
[/perl]
Let go through the codes for different scenarios:
Example 1: Sorting an array of strings (case-sensitive and case-insensitive examples)
[perl]
#!/usr/bin/perl
use strict;
use warnings;
my @strarr = qw(two Two six Six alien Coders Alien coderS);
my @sorted = sort {$a cmp $b} @strarr; # same result as of sort @strarr
my @sortedcase = sort { uc $a cmp uc $b } @strarr; #case-insensitivie
print “\n@sorted\n@sortedcase\n”;
[/perl]
Output:
Alien Coders Six Two alien coderS six two
alien Alien Coders coderS six Six two Two
Note: try to always use case insensitive for better string sorting results.
Example 2: Sorting an array of numbers
The Perl sort function sorts by strings instead of by numbers. If you do it in general way it would fetch unexpected result.
[perl] #!/usr/bin/perl
use strict;
use warnings;
my @numbers = (23, 1, 22, 7, 109, 9, 65, 3, 01, 001);
my @sorted_numbers = sort @numbers;
print “@sorted_numbers\n”;
[/perl]
The output you would see would be:
001 01 1 109 22 23 3 65 7 9
To sort numerically, declare your own sort block and use the binary equality operator i.e. flying saucer operator <=>:
[perl]
#!/usr/bin/perl
use strict;
use warnings;
my @numbers = (23, 1, 22, 7, 109, 9, 65, 3, 01, 001);
my @sorted_numbers = sort {$a <=> $b} @numbers;
print “@sorted_numbers\n”;
[/perl]
The output would now be:
1 01 001 3 7 9 22 23 65 109
Note that $a and $b do not need to be declared, even with use strict on, because they are special sorting variables.
Example 3: Sorting array backwards (for string and numbers)
To sort backwards you need to declare your own sort block, and simply put $b before $a. or use reverse keyword after simple sort.
For example, the standard sort is as follows:
[perl] #!/usr/bin/perl
use strict;
use warnings;
my @strings = qw(Jassi Alien Coders);
my @sorted_strings = sort @strings;
print “@sorted_strings\n”;
[/perl]
The output would be:
Alien Coders Jassi
To do the same, but in reverse order:
[perl]
#!/usr/bin/perl
use strict;
use warnings;
my @strings = qw(Jassi Alien Coders);
my @sorted_strings = sort {$b cmp $a} @strings; # or reverse sort @strings
print “@sorted_strings\n”;
[/perl]
The output is:
Jassi Coders Alien
And for numbers:
[perl]
#!/usr/bin/perl
use strict;
use warnings;
my @numbers = (23, 1, 22, 7, 109, 9, 65, 3);
my @sorted_numbers = sort {$b <=> $a} @numbers; # or reverse sort {$aó $b} @numbers
print “@sorted_numbers\n”;
[/perl]
The output is:
109 65 23 22 9 7 3 1
This was all about sorting array elements alphabetically or numerically. Now we will see how sorting works on hash elements.
Example 4: Sorting hashes by keys
You can use sort to order hashes. For example, if you had a hash as follows:
Suppose we want to display the members for each community sorted alphabetically or say by keys, then this code will do so:
[perl]
#!/usr/bin/perl
use strict;
use warnings;
my %members = (
C => 1,
Java => 7,
Perl => 12,
Linux => 3,
Hacking => 8,
);
foreach my $language (sort keys %members) {
print $language . “: ” . $members{$language} . “\n”;
}
[/perl]
Output:
C: 1
Hacking: 8
Java: 7
Linux: 3
Perl: 12
If you want to sort the same hash by the values (i.e. the users beside each programming language), you could do the following:
[perl]
#!/usr/bin/perl
use strict;
use warnings;
my %members = (
C => 1,
Java => 7,
Perl => 12,
Linux => 3,
Hacking => 8,
);
# Using <=> instead of cmp because of the numbers
foreach my $language (sort {$members{$a} <=> $members{$b}} keys %members){
print $language . “: ” . $members{$language} . “\n”;
}
[/perl]
Output:
C: 1
Linux: 3
Java: 7
Hacking: 8
Perl: 12
Example: 5 Sorting complex data structures
We can also use sort function to sort complex data structures. For example, suppose we have an array of hashes (anonymous hashes) like:
[perl]
my @aliens = (
{ name => ‘Jassi’, age => 28},
{ name => ‘Somnath’, age => 27},
{ name => ‘Ritesh’, age => 24},
{ name => ‘Santosh’, age => 29},
{ name => ‘Ranjan’, age => 26},
{ name => ‘Kaushik’, age => 25},
);
[/perl]
And we wish to display the data about the people by name, in alphabetical order, we could do the following:
[perl]
#!/usr/bin/perl
use strict;
use warnings;
my @aliens = (
{ name => ‘Jassi’, age => 28},
{ name => ‘Somnath’, age => 27},
{ name => ‘Ritesh’, age => 24},
{ name => ‘Santosh’, age => 29},
{ name => ‘Ranjan’, age => 26},
{ name => ‘Kaushik’, age => 25},
);
foreach my $person (sort {$a->{name} cmp $b->{name}} @aliens) {
print $person->{name} . ” is ” . $person->{age} . “\n”;
}
[/perl]
The output is:
Jassi is 28
Kaushik is 25
Ranjan is 26
Ritesh is 24
Santosh is 29
Somnath is 27
Sorting the same hash by age and using a subroutine (inline function)
Rather than writing the code inline, you can also pass in a subroutine name. The subroutine needs to return an integer less than, equal to, or greater than 0. Do not modify the $a and $b variables as they are passed in by reference, and modifying them will probably confuse your sorting.
[perl]
#!/usr/bin/perl
use strict;
use warnings;
my @aliens = (
{ name => ‘Jassi’, age => 28},
{ name => ‘Somnath’, age => 27},
{ name => ‘Ritesh’, age => 24},
{ name => ‘Santosh’, age => 29},
{ name => ‘Ranjan’, age => 26},
{ name => ‘Kaushik’, age => 25},
);
foreach my $person (sort agecomp @aliens) {
# it just replaced {$a->{age} <=> $b->{age}} by agecomp inline function
print $person->{name} . ” is ” . $person->{age} . ” years old\n”;
}
sub agecomp {
$a->{age} <=> $b->{age};
}
[/perl]
The output would be:
Ritesh is 24 years old
Kaushik is 25 years old
Ranjan is 26 years old
Somnath is 27 years old
Jassi is 28 years old
Santosh is 29 years old
To find out more on sort function, run the command on Linux box:
perldoc -f sort
Visitor Rating: 1 Stars
Visitor Rating: 5 Stars