Searching...
Thursday 11 July 2013

Sorting Arrays :: continued


Sorting an Array Naturally

The natsort() function is intended to offer a sorting mechanism comparable to the mechanisms that people normally use. Its prototype follows:

void natsort(array array)

The PHP manual offers an excellent example, shown here, of what it means to sort an array “naturally.” Consider the following items: 

picture1.jpg, picture2.jpg, picture10.jpg, picture20.jpg.

Sorting these items using typical algorithms results in the following ordering:

picture1.jpg, picture10.jpg, picture2.jpg, picture20.jpg

Certainly not what you might have expected, right? The natsort() function resolves this dilemma, sorting the array in the order you would expect, like so:

picture1.jpg, picture2.jpg, picture10.jpg, picture20.jpg

Case-Insensitive Natural Sorting

The function natcasesort() is functionally identical to natsort(), except that it is case insensitive:

void natcasesort(array array)

Returning to the file-sorting dilemma raised in the natsort() section, suppose that the pictures are named like this:
 
Picture1.JPG, picture2.jpg, PICTURE10.jpg, picture20.jpg
The natsort() function would do its best, sorting these items like so:

PICTURE10.jpg, Picture1.JPG, picture2.jpg, picture20.jpg

The natcasesort() function resolves this idiosyncrasy, sorting as you might expect:

Picture1.jpg, PICTURE10.jpg, picture2.jpg, picture20.jpg

Sorting an Array by Key Values

The ksort() function sorts an array by its keys, returning TRUE on success and FALSE otherwise. Its prototype follows:

integer ksort(array array [, int sort_flags])

If the optional sort_flags parameter is included, the exact sorting behavior is determined by its value, as described in the sort() section. Keep in mind that the behavior will be applied to key sorting but not to value sorting.

Sorting Array Keys in Reverse Order

The krsort() function operates identically to ksort(), sorting by key, except that it sorts in reverse (descending) order. Its prototype follows:

integer krsort(array array [, int sort_flags])

Sorting According to User-Defined Criteria

The usort() function offers a means for sorting an array by using a user-defined comparison algorithm, embodied within a function. This is useful when you need to sort data in a fashion not offered by one of PHP’s built-in sorting functions. Its prototype follows:

void usort(array array, callback function_name)

The user-defined function must take as input two arguments and must return a negative integer, zero, or a positive integer, respectively, based on whether the first argument is less than, equal to, or greater than the second argument. Not surprisingly, this function must be made available to the same scope in which usort() is being called.
A particularly applicable example of where usort() comes in handy involves the ordering of American-format dates (month, day, year, as opposed to day, month, year used by most other countries). Suppose that you want to sort an array of dates in ascending order. While you might think the sort() or natsort() functions are suitable for the job, as it turns out, both produce undesirable results.

The only recourse is to create a custom function capable of sorting these dates in the correct ordering:

<?php
$dates = array('10-10-2011', '2-17-2010', '2-16-2011',
'1-01-2013', '10-10-2012');
sort($dates);
echo "<p>Sorting the array using the sort() function:</p>";
print_r($dates);
natsort($dates);
echo "<p>Sorting the array using the natsort() function: </p>";
print_r($dates);
function DateSort($a, $b) {
// If the dates are equal, do nothing.
if($a == $b) return 0;
// Disassemble dates
list($amonth, $aday, $ayear) = explode('-',$a);
list($bmonth, $bday, $byear) = explode('-',$b);
// Pad the month with a leading zero if leading number not present
$amonth = str_pad($amonth, 2, "0", STR_PAD_LEFT);
$bmonth = str_pad($bmonth, 2, "0", STR_PAD_LEFT);
// Pad the day with a leading zero if leading number not present
$aday = str_pad($aday, 2, "0", STR_PAD_LEFT);
$bday = str_pad($bday, 2, "0", STR_PAD_LEFT);
// Reassemble dates
$a = $ayear . $amonth . $aday;
$b = $byear . $bmonth . $bday;
// Determine whether date $a > $date b
return ($a > $b) ? 1 : -1;
}
usort($dates, 'DateSort');
echo "<p>Sorting the array using the user-defined DateSort() function: </p>";
print_r($dates);
?>

This returns the following (formatted for readability):

Sorting the array using the sort() function:
Array ( [0] => 1-01-2013 [1] => 10-10-2011 [2] => 10-10-2012
[3] => 2-16-2011 [4] => 2-17-2010 )

Sorting the array using the natsort() function:
Array ( [0] => 1-01-2013 [3] => 2-16-2011 [4] => 2-17-2010
[1] => 10-10-2011 [2] => 10-10-2012 )

Sorting the array using the user-defined DateSort() function:
Array ( [0] => 2-17-2010 [1] => 2-16-2011 [2] => 10-10-2011
[3] => 10-10-2012 [4] => 1-01-2013 )

0 comments:

Post a Comment

 
Back to top!