usort

(PHP 4, PHP 5, PHP 7, PHP 8)

usort Ordina un array mediante una funzione definita dall'utente

Descrizione

usort(array $&array, callback $cmp_function): bool

Ordina i valori di un array mediante una funzione di comparazione definita dall'utente. Se si vuole ordinare un array con dei criteri non usuali, si deve usare questa funzione.

La funzione di comparazione deve restituire un intero minore, uguale o superiore a zero se il primo elemento è da considerarsi rispettivamente minore, uguale o maggiore del secondo.

Nota:

Se due parametri vengono valutati come uguali, il loro ordinamento nell'array ordinato è indefinito. Fino al PHP 4.0.6 le funzioni definite dall'utente mantenevano l'ordine originario per questi elementi, ma con il nuovo algoritmo di ordinamento introdotto con la versione 4.1.0 questo non succede più dal momento che non c'è un modo per ottenerlo in maniera efficiente.

Restituisce true in caso di successo, false in caso di fallimento.

Example #1 esempio di usort()

<?php
function cmp($a, $b)
{
if (
$a == $b) {
return
0;
}
return (
$a < $b) ? -1 : 1;
}

$a = array(3, 2, 5, 6, 1);

usort($a, "cmp");

while (list(
$chiave, $valore) = each($a)) {
echo
"$chiave: $valore\n";
}
?>

Questo esempio mostrerà:

0: 1
1: 2
2: 3
3: 5
4: 6

Nota:

Ovviamente, in questo caso banale di ordinamento decrescente la funzione sort() sarebbe stata più appropriata.

Example #2 esempio di usort() con un array multidimensionale

<?php
function cmp($a, $b)
{
return
strcmp($a["frutto"], $b["frutto"]);
}

$frutti[0]["frutto"] = "limoni";
$frutti[1]["frutto"] = "arance";
$frutti[2]["frutto"] = "uva";

usort($frutti, "cmp");

while (list(
$chiave, $valore) = each($frutti)) {
echo
"\$frutti[$chiave]: " . $valore["frutto"] . "\n";
}
?>

Quando si ordina un array multidimensionale, $a e $b contengono riferimenti al primo indice dell'array.

Questo esempio mostrerà:

$frutti[0]: arance
$frutti[1]: limoni
$frutti[2]: uva

Example #3 esempio di usort() usando una funzione membro di un oggetto

<?php
class OggettoTest {
var
$nome;

function
OggettoTest($nome)
{
$this->nome = $nome;
}

/* Questa è la funzione statica di comparazione: */
function comp_ogg($a, $b)
{
$al = strtolower($a->nome);
$bl = strtolower($b->nome);
if (
$al == $bl) {
return
0;
}
return (
$al > $bl) ? +1 : -1;
}
}

$a[] = new OggettoTest("c");
$a[] = new OggettoTest("b");
$a[] = new OggettoTest("d");

usort($a, array("OggettoTest", "comp_ogg"));

foreach (
$a as $voce) {
echo
$voce->nome."\n";
}
?>

Questo esempio mostrerà:

b
c
d

Vedere anche uasort(), uksort(), sort(), asort(), arsort(),ksort(), natsort() e rsort().

add a note

User Contributed Notes 11 notes

up
21
Hayley Watson
12 years ago
As the documentation says, the comparison function needs to return an integer that is either "less than, equal to, or greater than zero". There is no requirement to restrict the value returned to -1, 0, 1.<?phpusort($array, function($a, $b) {    if($a->integer_property > $b->integer_property) {        return 1;    }    elseif($a->integer_property < $b->integer_property) {        return -1;    }    else {        return 0;    }});?>can be simplified to<?phpusort($array, function($a, $b) {    return $a->integer_property - $b->integer_property;});?>This of course applies to any comparison function that calculates an integer "score" for each of its arguments to decide which is "greater".
up
12
luke dot semerau at gmail dot com
16 years ago
If you need to use usort with a key in the calling method, I wrote this as a utility:<?phpfunction usort_comparison($obj, $method, $key) {    $usorter = &new Usort($obj, $method, $key);    return array($usorter, "sort");}class Usort {    function __construct($obj, $method, $key) {        $this->obj = $obj;        $this->method = $method;        $this->key = $key;    }    function sort($a, $b) {        return call_user_func_array(array($this->obj, $this->method), array($a, $b, $this->key));    }}?><?phprequire_once("util/usort.php");class Foo {    $items = array(FooBar(13), FooBar(2));    public function sorter() {        usort($this-items, usort_comparison("Foo", "_cmp", "item"));    }    public static function _cmp($a, $b, $key) {         return strcasecmp($a->$key, $b->$key);    }}class FooBar {    public $item;    function __construct($val) {        $this->item = $val;    }}?>~ simple example... but in the way I need to use it was the key was used in a switch statement to choose the different member of the object to compare against dynamically (as in, sort by x or y or z)
up
14
mkr at binarywerks dot dk
22 years ago
If you want to sort an array according to another array acting as a priority list, you can use this function.

<?php
function listcmp($a, $b)
{
  global $order;

  foreach($order as $key => $value)
    {
      if($a==$value)
        {
          return 0;
          break;
        }

      if($b==$value)
        {
          return 1;
          break;
        }
    }
}

$order[0] = "first";
$order[1] = "second";
$order[2] = "third";

$array[0] = "second";
$array[1] = "first";
$array[2] = "third";
$array[3] = "fourth";
$array[4] = "second";
$array[5] = "first";
$array[6] = "second";

usort($array, "listcmp");

print_r($array);
?>
up
8
derek at luddite dot net
24 years ago
Needed a date sort and I didn't know if one was available so I wrote one. Maybe it'll help someone:

<?php
function DateSort($a,$b,$d="-") {
    if ($a == $b) {
        return 0;
    } else {  //Convert into dates and compare
        list($am,$ad,$ay)=split($d,$a);
        list($bm,$bd,$by)=split($d,$b);
        if (mktime(0,0,0,$am,$ad,$ay) < mktime(0,0,0,$bm,$bd,$by)) {
            return -1;
        } else {
            return 1;
        }
    }
}
?>

$d is the delimeter
up
5
sydney at totoche dot org
19 years ago
Instead of doing  :

<?php $strc = strcmp( strtolower($a[$f]), strtolower($b[$f]) ); ?>

you could do this : 

<?php $strc = strcasecmp( $a[$f], $b[$f] ); ?>

which is more efficient and is does case insensitive comparison according to the current locale.
up
2
gus dot antoniassi at gmail dot com
6 years ago
This is a simple way to sort based on a "priority list":<?php$order = [1,3,0,2];$arr =   [    [ 'id' => 0 ],    [ 'id' => 1 ],    [ 'id' => 2 ],    [ 'id' => 3 ],];uasort(    $arr,     function ($a, $b) use ($order) {        return array_search($a['id'], $order) <=> array_search($b['id'], $order);     });print_r($arr);?>This will return:Array(    [1] => Array        (            [id] => 1        )    [3] => Array        (            [id] => 3        )    [0] => Array        (            [id] => 0        )    [2] => Array        (            [id] => 2        ))Note that if you have a value in $arr that is not on the $order list, you will need additional checks since the array_search function returns FALSE for undefined indexes.
up
4
inigo dot grimbergen at gmail dot com
8 years ago
to sort with numeric and empty values  and have the smallest on top:<?php    usort($list, function($a, $b) {        if( $a == null && $b != null ) return 1;        if( $a != null && $b == null ) return -1;        return $a > $b ? 1 : -1;    });?>returns123nullnullnull
up
3
andi_mclean at ntlworld dot com
13 years ago
I needed a sort method that would sort strings but take note of any numbers and would compare them as number. I also want to ignore any non alphanumerical characters.Eg.Slot 1 ExampleSlot 10 ExampleSlot 2 ExampleShould infact beSlot 1 ExampleSlot 2 ExampleSlot 10 Example<?phpfunction sort_with_numbers($a , $b) {    $a = explode(' ',$a);    $b = explode(' ',$b);    $size = min(count($a), count($b));    for($index =0; $index < $size; ++$index) {        $a1 = ereg_replace("[^A-Za-z0-9]", "",$a[$index]);        $b1 = ereg_replace("[^A-Za-z0-9]", "",$b[$index]);        $equal = 0;        if (is_numeric($a1) && is_numeric($b1)) {            $equal = $a1 - $b1;        } else {            $equal = strcasecmp($a1,$b1);        }        if ($equal < 0) {            return -1;        }        if ($equal > 0) {            return 1;        }    }    return count($a) - count($b);    }?>
up
1
chris at candm dot org dot uk
6 years ago
In case anyone is interested, comparative timings over 100000000 runsBased on comparing integers (500 and 501)Spaceship:4()?: operator:10Subtraction:2Based on comparing floats (500.1 and 501.3) (caveats noted)Spaceship:5()?: operator:9Subtraction:3Based on comparing strings ("five" and "four")Spaceship:7()?: operator:17(Subtraction obviously not available)Note: a dummy run was done with an empty loop and the elapsed time for this was subtracted from each of the above times so that they reflect ONLY the time to do the comparisons. As for significance. unless you are doing very large numbers of comparisons where spaceships are the order of the day, the difference is insignificant.
up
2
bo at erichsen dot com
24 years ago
when using usort to refer to a function inside a class i have succesfully used:

<?php usort($myarray,array($this,"cmp")); ?>
up
1
rh at 20i dot com
1 year ago
A sort function to sort elements by a reference order.function sort_by_reference(array $array_to_sort, array $reference_array): array {    usort($array_to_sort, function($a, $b) use ($reference_array) {        $pos_a = array_search($a, $reference_array);        $pos_b = array_search($b, $reference_array);        return $pos_a - $pos_b;    });    return $array_to_sort;}// Example usage$reference_array = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"];$array_to_sort = ["three", "one", "seven", "four", "ten"];$sorted_array = sort_by_reference($array_to_sort, $reference_array);// Print the result to verify the sortingprint_r($sorted_array);```Array(    [0] => one    [1] => three    [2] => four    [3] => seven    [4] => ten)```
To Top