Articles

The month of PHP functions : a different sort

  • Ecrit par Damien Seguy
  • lundi 26 mars 2007
Image pour le titre du contenu

Ce document est aussi disponible en français fr 


With SQL, there is a convenient clause to sort data : ORDER BY. And what about PHP ?

With PHP, there is actually quite a load of them. There is the *sort family. Those functions sort in the spot an array, like this :

<?php
$array = array(3,45,6,7,3,2,);
sort($array);
// now, $array is sorted.
?>

To easily remember all the different variation of sort, here is a simple table with all prefixes. '' (nothing), for sorting on values, a for sortin on values and keeping the related keys (associated sort), and k for sorting on keys and  keeping the related key.

Then, '' (nothing) for ascending, r for descending and u for user. This last type of sort require a user desfined function to make the comparison (hence the name), and do no have a r(-everse) prefix version : one juste have to update the sorting function and reverse the comparison function.

  Values Keys Values and keys
Direct sort() ksort() asort()
Reverse rsort() krsort() arsort()
User usort() uksort() uasort()

Unlike SQL, PHP has yet another interesting sorting function : natsort(), which is a natural sort. What is natural here is that the sort will close to human sorting. The algorithme tries to understand figures includes in the string values, and use them as numbers instead of figures. Let see an example to fully understand.

In the following array, I have gathered names of photos : they are from a digital camera, which uses an internal counter to give unique names to each file.

<?php
$tableau = array("DSCN8.JPG", "DSCN14.JPG", "DSCN1546.JPG", "DSCN094.JPG");
 
 
sort($tableau);
print_r($tableau);
 
 
natsort($tableau);
print_r($tableau);
?>

This script displays :

Array
(
    [0] => DSCN094.JPG
    [1] => DSCN14.JPG
    [2] => DSCN1546.JPG
    [3] => DSCN8.JPG
)
Array
(
    [0] => DSCN094.JPG
    [3] => DSCN8.JPG
    [1] => DSCN14.JPG
    [2] => DSCN1546.JPG
)

In the first sort, names are sorted by figure : 0 before 1 before 8. In the second sort, numbers are identified, and sorted accordingly : 8 is now before 14 and before 1546. Take note of 094, which is not identified as 94.

Another feature of ORDER BY is that it will sort columns in cascading style. When it is provided with several columns, it will use the first columun as primary sort. In case of identical value, it will use the second column to distinguish them.

Moreover, sorting with ORDER BY keeps all lines consistent : all values that were in the same row are sorted accordingly. With PHP, we can sort an array, and may be keep the relation with the key : that make only 2 columns. Could we do the same for more columns?

This is a task for array_multisort(). This function takes several array, and sort them the same way. The sorting is based upon the first array provided, and, in case of egality, based on the second array, etc.

<?php
 
 
$t1 = array(2,3,5,7,11);
$t2 = array('deux','trois','cinq','sept','onze');
$t3 = array(5=> 'zwei','drei','f&uuml;nf','sieben','elf');
 
 
// sorting by French litteral numbers
array_multisort($t2, $t1, $t3);
print_r($t1);
print_r($t2);
print_r($t3);
?>

This scripts displays :

Array
(
    [0] => 5
    [1] => 2
    [2] => 11
    [3] => 7
    [4] => 3
)
Array
(
    [0] => cinq
    [1] => deux
    [2] => onze
    [3] => sept
    [4] => trois
)
Array
(
    [0] => f&uuml;nf
    [1] => zwei
    [2] => elf
    [3] => sieben
    [4] => drei
)

Take note :
  • natcasesort() does the same natural sorting, without taking care of string case.
  • array_multisort() omit the index : one just have to turn a key => value array into two separate array to achieve the same sorting.
  • array_multisort() works well with references : no need to work hard to sort a multidimensionnal array with it.
  • array_multisort() also accept extra argument to fix the sorted scalar type (number, text or guess it) and the sorting order (asc or desc).
< Précédent   Suivant >

Commentaires

Vous pouvez ajouter votre commentaire!


Vous devez vous connecter pour commenter