Sorting techniques in Perl

29
Sorting techniques in Perl Presented by Yogesh Sawant September 2010

description

This course provides you with knowledge and skills in the areas of:1. Sorting numbers2. Sorting strings3. Sorting arrays4. Sorting hashesThis course does not cover sorting algorithms. Instead, it is about sorting various types of data in Perl.

Transcript of Sorting techniques in Perl

Page 1: Sorting techniques in Perl

Sorting techniques in Perl

Presented by Yogesh SawantSeptember 2010

Page 2: Sorting techniques in Perl

Course Goal

• This course provides you with knowledge and skills in the areas ofo Sorting numberso Sorting stringso Sorting arrayso Sorting hashes

• This course does not cover sorting algorithms. Instead, it is about sorting various types of data in Perl.

Page 3: Sorting techniques in Perl

Course Map• Sorting in Perl• Sorting Numbers• Sorting alphanumeric strings• Case insensitive sorting• Sorting based on length of strings• Sorting a hash• Sorting a hash by values• Sorting a two dimensional array• Sorting a hash of arrays• Sorting an array of hashes• Sorting a hash of hashes

Page 4: Sorting techniques in Perl

The Usual Chore

• Perl's built-in function sort provides quick and easy method of sorting data

@sorted = sort @array;

• Sorts the list and returns the sorted list

• The default sorting order is string comparisono Defined null strings sort before everything else

o Undefined values sort before defined null strings

• Perl 5.6 and earlier use quick sort algorithm

• Perl 5.7 uses merge sort algorithm that is more stable than quick sort

• Perl 5.8 has a sort pragma for limited control of the sort

Page 5: Sorting techniques in Perl

• How about sorting numbers? That's easy with the help of global variables $a and $b

@numbers_sorted = sort { $a <=> $b } @numbers;

• We have provided a subroutine to the sort function, which replaces the default method of comparisons

• Perl's numeric comparison operator <=> is useful here

• Alternatively,

sub numerically { $a <=> $b }

@numbers_sorted = sort numerically @numbers;

o The subroutine may not be recursive, loop control operators shouldn't be used either

o Two elements to be compared are not passed into it via @_ but by temporarily setting global variables $a and $b

o Variables $a and $b are aliases to the real values, so don't modify them in the subroutine

Sorting Numbers

Page 6: Sorting techniques in Perl

• To sort numbers in descending order, we could reverse the order of $a and $b as:

@desc_sorted = { $b <=> $a } @numbers;• Alternatively,

sub numeric_desc { $b <=> $a } @desc_sorted = sort numeric_desc @numbers;

• Another way using the reverse built-in function, @desc_sorted = reverse sort { $a <=> $b } @numbers;

Sorting Numbers

Page 7: Sorting techniques in Perl

• What if I have data such as child1, child3, child11, child21, child5, child24 and I want to sort them based on the numbers that follow after the alphabetic part?

@alphabetic_sorted = sort { substr($a, 5) <=> substr($b, 5) } @alphabetic;

• We've extracted the numeric part from the alphanumeric string and used it for comparisons

Alphanumeric

Page 8: Sorting techniques in Perl

• I have a list of words that I want to sort without regard to upper case or lower case

• Perl's built-in function lc, along with cmp operator helps us in this case:

sub without_case { lc($a) cmp lc($b) }

@sorted_strings = sort without_case @strings;

The case does not matter

Page 9: Sorting techniques in Perl

• I want to sort strings based on their lengths

• Perl's built-in function length makes our task easy: sub by_length { length $a <=> length $b }

@lengthwise_sorted = sort by_length @strings;

Who's the shortest

Page 10: Sorting techniques in Perl

Course Map• Sorting in Perl• Sorting Numbers• Sorting alphanumeric strings• Case insensitive sorting• Sorting based on length of strings• Sorting a hash• Sorting a hash by values• Sorting a two dimensional array• Sorting a hash of arrays• Sorting an array of hashes• Sorting a hash of hashes

Page 11: Sorting techniques in Perl

• How do I get key-value pairs of a hash in the sorted order as per keys?

for $key (sort keys %hash) {      # $key and $hash{$key} are the key-value pairs }

• If the keys are numeric, for $key (sort { $a <=> $b } keys %hash) {      # $key and $hash{$key} are the key-value pairs }

Sorting a hash

Page 12: Sorting techniques in Perl

• How do I get key-value pairs of a hash in the sorted order as per values? for $key (sort { $hash{$a} cmp $hash{$b} } keys %hash) {

  # $key and $hash{$key} are the key-value pairs }

• If the values are numeric for $key (sort { $hash{$a} <=> $hash{$b} } keys %hash) {

     # $key and $hash{$key} are the key-value pairs }

Sorting a hash by values

Page 13: Sorting techniques in Perl

      my @array = ( ["Kaka", "Maicon"], ["Romero", "Tevez", "Messi"], ["Fierro", "Suazo", "Carmona"], );

• Sort ASCIIbetically for my $row (@array) {      print join(", ", sort(@$row)), "\n"; }

• Sort based on length of strings for my $row (@array) { print join(", ", sort { length($a) <=> length($b)} (@$row)), "\n";

}

Two Dimensional Array

Page 14: Sorting techniques in Perl

Course Map• Sorting in Perl• Sorting Numbers• Sorting alphanumeric strings• Case insensitive sorting• Sorting based on length of strings• Sorting a hash• Sorting a hash by values• Sorting a two dimensional array• Sorting a hash of arrays• Sorting an array of hashes• Sorting a hash of hashes

Page 15: Sorting techniques in Perl

   my %hash = ( Mexico => ["Ricardo", "Blanco", "Franco"], Argentina => ["Romero", "Tevez", "Messi"], Chile => ["Fierro", "Suazo", "Carmona"], );

• Sort ASCIbetically based on keys of hash• Sort based on length of keys of hash• Sort ASCIIbetically based on strings in the arrays• Sort based on lengths of strings in the arrays• Sort ASCIbetically based on keys of hash and then sort ASCIIbetically

based on strings in the arrays

Hash of Arrays

Page 16: Sorting techniques in Perl

• Sort ASCIbetically based on keys of %hash for my $key (sort keys %hash) {      print $key, "\t", @{ $hash{$key} }, "\n"; }

• Sort based on length of keys of %hash for my $key (sort { length($a) <=> length($b) } keys %hash) {

     print $key, "\t", @{ $hash{$key} }, "\n"; }

• Sort ASCIIbetically based on strings in the arrays for my $key (keys %hash) {     print $key, "\t", join(", ", sort @{ $hash{$key} }), "\n";

}

Hash of Arrays

Page 17: Sorting techniques in Perl

• Sort based on lengths of strings in the arrays for my $key (keys %hash) {     print $key, "\t", join(", ", sort { length($a) <=> length($b) } @{ $hash{$key} }), "\n";

}

• Sort ASCIbetically based on keys of %hash and then sort ASCIIbetically based on strings in the arrays for my $key (sort keys %hash) {    print $key, "\t", join(", ", sort@ { $hash{$key} }), "\n";

}

Hash of Arrays

Page 18: Sorting techniques in Perl

Course Map• Sorting in Perl• Sorting Numbers• Sorting alphanumeric strings• Case insensitive sorting• Sorting based on length of strings• Sorting a hash• Sorting a hash by values• Sorting a two dimensional array• Sorting a hash of arrays• Sorting an array of hashes• Sorting a hash of hashes

Page 19: Sorting techniques in Perl

        my @array = ( {      Maicon => "DF", Elano => "MF", Robinho => "FW", }, {      Heinz => "DF", Messi => "FW", Milito => "FW", }, {      Fierro => "MF", Medel => "DF", Suazo => "FW", }, );

• sort ASCIIbetically based on keys of the hashes• sort based on length of keys of the hashes• sort ASCIIbetically based on values of the hashes

Array of Hashes

Page 20: Sorting techniques in Perl

Array of Hashes

• sort ASCIIbetically based on keys of the hashes for my $href (@array) {     for my $key (sort keys %$href) {        print $key, " => ", $href->{$key}, "\n";     }     print "\n"; }

• sort based on length of keys of the hashes for my $href (@array) {     for my $key (sort { length($a) <=> length($b) } keys %$href) {

     print $key, " => ", $href->{$key}, "\n";    }     print "\n"; }

Page 21: Sorting techniques in Perl

Array of Hashes

• sort ASCIIbetically based on values of the hashes print "\n\n sort ASCIIbetically based on values of the hashes\n";

for my $href (@array) {      for my $key (sort { ($href->{$a}) cmp ($href->{$b}) } keys %$href) {

         print $key, " => ", $href->{$key}, "\n";      }      print "\n"; }

Page 22: Sorting techniques in Perl

Course Map• Sorting in Perl• Sorting Numbers• Sorting alphanumeric strings• Case insensitive sorting• Sorting based on length of strings• Sorting a hash• Sorting a hash by values• Sorting a two dimensional array• Sorting a hash of arrays• Sorting an array of hashes

• Sorting a hash of hashes

Page 23: Sorting techniques in Perl

Hash of Hashes

my %hash = (

    toons => {

    daffy => 'duck',

    tom => 'jerry',

    road => 'runner',

    },

    cars => {

    tiny => 'nano',

    small => 'wagonR',

    },

    sites => {

    mail => 'yahoo.com',

    groups => 'google.com',

    },

);

• Sort ASCIIbetically based on keys of %hash

• Sort based on length of keys of %hash

• Sort ASCIIbetically based on keys of inner hash

• Sort based on length of keys of inner hash

• Sort ASCIIbetically based on values of inner hash

• Sort based on length of values of inner hash

• Sort based on length of keys of %hash and then ASCIIbetically on keys of inner hashes

• Sort ASCIIbetically based on keys of %hash and then ASCIIbetically on keys of inner hashes

Page 24: Sorting techniques in Perl

Hash of Hashes

• Sort ASCIIbetically based on keys of %hash for my $key (sort keys %hash) {

   print "\n $key: \n";

  for my $key_inner (keys %{ $hash{$key} }) {

     print $key_inner, " = ", $hash{$key}{$key_inner}, "\n";

   }

}

• Sort based on length of keys of %hash for my $key (sort {length($a) <=> length($b)} keys %hash) {

print "\n $key: \n";

for my $key_inner (keys %{ $hash{$key} }) {

print $key_inner, " = ", $hash{$key}{$key_inner}, "\n";

}

}

Page 25: Sorting techniques in Perl

Hash of Hashes

• Sort ASCIIbetically based on keys of inner hash for my $key (keys %hash) {

print "\n $key: \n";

for my $key_inner (sort keys %{ $hash{$key} }) {

print $key_inner, " = ", $hash{$key}{$key_inner}, "\n";

}

}

• Sort based on length of keys of inner hash for my $key (keys %hash) { print "\n $key: \n"; for my $key_inner (sort { length($a) <=> length($b) } keys

%{ $hash{$key} }) { print $key_inner, " = ", $hash{$key}{$key_inner}, "\n"; } }

Page 26: Sorting techniques in Perl

Hash of Hashes

• Sort ASCIIbetically based on values of inner hash for my $key (keys %hash) {

   print "\n $key: \n";

   for my $key_inner (sort { $hash{Key}->{$a} cmp $hash{$key}->{$b} } keys %{ $hash{$key} }) {

      print $key_inner, " = ", $hash{$key}{$key_inner}, "\n";

     }

}

Page 27: Sorting techniques in Perl

Hash of Hashes

• Sort based on length of values of inner hash for my $key (keys %hash) {

   print "\n $key: \n";

  for my $key_inner (sort { length($hash{$key}{$a}) <=> length($hash{$key}{$b}) } keys %{ $hash{$key} }) {

      print $key_inner, " = ", $hash{$key}{$key_inner}, "\n";

   }

}

Page 28: Sorting techniques in Perl

Hash of Hashes

• Sort ASCIIbetically based on keys of %hash and then ASCIIbetically on keys of inner hashes for my $key (sort keys %hash) {   print "\n $key: \n";   for my $key_inner (sort keys %{ $hash{$key} }) {      print $key_inner, " = ", $hash{$key}{$key_inner}, "\n";

} }

Page 29: Sorting techniques in Perl

How to Learn More

• Interneto Perl documentation – sort function

http://perldoc.perl.org/functions/sort.htmlo A Fresh Look at Efficient Perl Sorting

http://www.sysarch.com/Perl/sort_paper.htmlo Sorting in Perl

http://raleigh.pm.org/sorting.html