Perl sort function Usage Summary and usage examples

Source: Internet
Author: User

A) Sort function usage

Sort LIST
Sort BLOCK LIST
Sort SubName LIST

The use of sort is in the form of 3. It sorts the list and returns the sorted lists. If the subname or Block,sort are ignored in the order of standard string comparisons (for example, ASCII order). If SubName is specified, it is actually the name of a child function that compares 2 list elements and returns an integer less than, equal to, or greater than 0, depending on the order in which the elements are sorted (ascending, identical, or descending). You can also provide a block as an anonymous sub-function instead of subname, and the effect is the same.

The 2 elements being compared are temporarily assigned to the variable $ A and $b. They are passed by reference, so do not modify $ A or $b. If you use a sub-function, it cannot be a recursive function.

II) Usage examples

1. Sort in numerical order

Copy CodeThe code is as follows:
@array = (8, 2, 32, 1, 4, 16);
Print join (", sort {$a <=> $b} @array)," \ n ";


The printing results are:

Copy CodeThe code is as follows: 1 2 4 8 16 32

The same is true of:

Copy CodeThe code is as follows: Sub numerically {$a <=> $b};
Print join (', sort numerically @array), ' \ n ';

It's easy to understand oh, it's just sort in the order of the natural numbers, and I'm not going to say it.

2.1 Sort in ASCII order (non-dictionary order)

Copy CodeThe code is as follows:
@languages = QW (Fortran lisp c C + + Perl python java);
Print join (', sort @languages), ' \ n ';

Printing results:

Copy CodeThe code is as follows: Perl c C + + Fortran Java Lisp python

This is equivalent to:

Copy CodeThe code is as follows: Print join (", sort {$a CMP $b} @languages)," \ n ";

In the order of ASCII, there is nothing to say oh.

Note that if you sort the numbers in ASCII order, the result may be different from what you think:

Copy CodeThe code is as follows:
Print join (', sort 1: one), ' \ n ';
1 10 11 2 3 4 5 6 7 8 9

2.2 In dictionary order sort

Copy CodeThe code is as follows:
Use locale;
@array = QW (ASCII ASCAP at_large atlarge A arp ARP);
@sorted = sort {($da = LC $a) =~ s/[/w_]+//g;
($DB = LC $b) =~ s/[/w_]+//g;
$da CMP $db;
} @array;
print "@sorted \ n";

The printing results are:

Copy CodeThe code is as follows: A arp ARP ASCAP ASCII atlarge at_large

The use locale is optional-it makes code compatibility better, if the original data contains international characters. The use locale affects the operation properties of CMP,LT,LE,GE,GT and some other functions-see Perllocale's man page for more details.

Note that the order of Atlarge and At_large is reversed in the output, although their sort order is the same (sort middle sub-function deletes the At_large middle underline). This can happen because the example runs on a Perl 5.005_02. Before Perl version 5.6, the sort function would not protect the order of keys with the same values. Perl version 5.6 and later versions will protect this order.

Note that, whether it's map,grep or sort, you need to protect this temporary variable $_ (sort is $ A and $b), and don't modify it.
In this code, they are re-assigned to $da and $DB before they are replaced by $ A or $b, so the substitution operation does not modify the original element.

3. Sort in descending order

Descending sort is easier, and it is possible to swap the positions of the CMP or <=> before and after the operation.

Copy CodeThe code is as follows: sort {$b <=> $a} @array;


or change the markup for the return value of the middle block or child function:

Copy CodeThe code is as follows: sort {-($a <=> $b)} @array;


Or use the reverse function (which is somewhat inefficient, but perhaps easy to read):

Copy CodeThe code is as follows: Reverse sort {$a <=> $b} @array;

4. Use multiple keys for sort

To sort with multiple keys, place all the comparison operations connected with or in a sub-function. Put the main comparison action in front, and secondary to the back.

Copy CodeThe code is as follows:
# An array of references to anonymous hashes
@employees = (
{first = ' Bill ', last = ' Gates ',
SALARY = 600000, age = 45},
{first = ' George ', last = ' Tester '
SALARY = 55000, age = 29},
{first = ' Steve ', last = ' Ballmer ',
SALARY = 600000, age = 41}
{first = ' Sally ', last = ' Developer ',
SALARY = 55000, age = 29},
{first = ' Joe ', last = ' Tester ',
SALARY = 55000, age = 29},
);
Sub seniority {
$b->{salary} <=> $a->{salary}
or $b->{age} <=> $a->{age}
or $a->{last} cmp $b->{last}
or $a->{first} cmp $b->{first}
}
@ranked = sort seniority @employees;
foreach $emp (@ranked) {
Print "$emp->{salary}/t$emp->{age}/t$emp->{first}
$emp->{last}\n ";
}

The printing results are:

Copy CodeThe code is as follows: 600000 Bill Gates
600000 Steve Ballmer
55000 Sally Developer
55000 George Tester
55000 Joe Tester

The code above looks complicated, and it's actually easy to understand. The elements of the @employees array are anonymous hashes. An anonymous hash is actually a reference that can be accessed with the operator, such as $employees[0]->{salary}, to the value of the SALARY corresponding to the first anonymous hash. So the above comparison is very clear, first compare the value of salary, and then compare the value of age, and then compare the last value, and finally compare the value. Note that the first 2 comparisons are in descending order, and the last 2 items are ascending, so don't confuse them.

5. Sort out a new array

Copy CodeThe code is as follows:
@x = QW (Matt Elroy Jane Sally);
@rank [Sort {$x [$a] CMP $x [$b]} 0: $ #x] = 0.. $ #x;
print "@rank \ n";

The printing results are:

Copy CodeThe code is as follows: 2 0 1 3

Is it a bit confusing here? It's clear to look carefully. 0.. $ #x是个列表, the value of which is the subscript for the @x array, which is 0 1 2 3. $x [$a] CMP $x [$b] is to compare the various elements in the @x in ASCII order. So the result of sort returns a list of @x's subscripts, sorted by the ASCII order of the @x element corresponding to the subscript.
Still don't understand what sort returns? Let's first print out the ASCII order of the elements in the @x:

Copy CodeThe code is as follows:
@x = QW (Matt Elroy Jane Sally);
Print join ', sort {$a CMP $b} @x;

The printing results are:

Copy CodeThe code is as follows: Elroy Jane Matt Sally

Their corresponding subscript in @x is 1 2 0 3, so the result of the sort returned above is the list of 1 2 0 3. @rank [1 2 0 3] = 0.. $ #x is just a simple array assignment operation
So the result of @rank is (2 0 1 3).

6. Press the keys to sort the hash

Copy CodeThe code is as follows:
%hash = (Donald = Knuth, Alan = Turing, John = Neumann);
@sorted = map {{($_ = = $hash {$_})}} sort keys%hash;
foreach $hashref (@sorted) {
($key, $value) = each% $hashref;
print "$key = $value \ n";
}

The printing results are:

Copy CodeThe code is as follows: Alan = Turing
Donald = Knuth
John = Neumann

The above code is not difficult to understand OH. Sort keys%hash Returns a list in the ASCII order of the%hash keys, then calculates it with a map, noting that the map uses the dual {{}}
Inside the {} is an anonymous hash oh, that is, the result of map is an anonymous hash list, understand it?
So the elements in the @sorted array are each anonymous hash, and the Key/value value can be accessed by using the% $hashref to reverse-reference it.

7. Sort the hash by values

Copy CodeThe code is as follows:
%hash = (Elliot = Babbage,
Charles = Babbage,
Grace = Hopper,
Herman = Hollerith
);
@sorted = map {{($_ = = $hash {$_})}}
Sort {$hash {$a} cmp $hash {$b}
or $a CMP $b
} keys%hash;
foreach $hashref (@sorted) {
($key, $value) = each% $hashref;
print "$key = $value \ n";
}

The printing results are:

Copy CodeThe code is as follows: Charles = Babbage
Elliot = Babbage
Herman = Hollerith
Grace = Hopper

Unlike hash keys, we cannot guarantee the uniqueness of the hash values. If you just sort the hash based on values, the sort order of 2 elements with the same value may change when you increase or delete other values. In order to obtain a stable result, the value should be the main sort, the key from the sort.

Here {$hash {$a} cmp $hash {$b} or $a CMP $b} first by value and then by key 2 sort Oh, the result of sort returned is the sorted keys list, and then this list is given to map for calculation, returning an anonymous hash list. The access method is the same as the previous, I am not an unknown.

8. Sort the words in the file and remove the duplicate

Copy CodeThe code is as follows:
Perl-0777ane ' $, = "\ n"; @uniq {@F} = (); Print sort keys%uniq ' file

Let's try this usage, I don't quite understand.
@uniq {@F} = () uses a hash slice to create a hash whose keys are the only words in the file;
This usage is semantically equivalent to $uniq{$F [0], $F [1], ... $F [$ #F]} = ()

The options are described below:

Copy CodeThe code is as follows:-0777-Reads the entire file instead of a single line
-A-auto-split mode, dividing rows into @f arrays
-e-Read and run scripts from the command line
-N-Traverse file by line: while (<>) {...}
$,-output field separator for the print function
File-file name

9. Efficient Sorting:orcish algorithm and Schwartzian conversion

The child functions for each key,sort are usually called multiple times. If you are very concerned about the sort run time, you can use the orcish algorithm or the Schwartzian conversion so that each key is calculated only 1 times
Consider the following example, which lists the sort files based on the date the file was modified.

Copy CodeThe code is as follows: # forcing algorithm--multiple accesses to disk per file
@sorted = sort {-M $a <=>-M $b} @filenames;

# Orcish algorithm--Create keys in hash
@sorted = sort {($modtimes {$a} | | =-M $a) <=>
($modtimes {$b} | | =-M $b)
} @filenames;


Very ingenious algorithm, isn't it? Because the modified date of the file is basically constant during the script run, so-M operation once, save it up.
The following is the usage of the Schwartzian transformation:

Copy CodeThe code is as follows: @sorted = Map ({$_->[0]}
Sort ({$a->[1] <=> $b->[1]}
Map ({[$_,-M]} @filenames)
)
);


This code combines several layers of map,sort, remembering the methods I mentioned before, and looking forward from behind. Map ({[$_,-M]} @filenames) returns a list of elements that are anonymous, the first value of the anonymous array is the file name, and the second value is the modified date of the document.

Sort ({$a->[1] <=> $b->[1]} ... The list of anonymous arrays generated above is then sort, based on the modified date of the file.
Sort returns the result of a sorted, anonymous array.

Outermost map ({$_->[0]} ... Simply, it extracts the file name from the anonymous array generated by the above sort. The file name is sort over by the modified date, and each file runs only once-M.
This is the famous Schwartzian conversion, and this usage is popular with Perl users abroad.

Perl sort function Usage Summary and usage examples

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.