usort

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

usortOrdena um array pelos valores utilizando uma função de comparação definida pelo usuário

Descrição

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

Essa função irá ordenar um array pelos valores usando uma função de classificação definida pelo usuário. Se o array precisar ser ordenado utilizando um critério não trivial, você deve usar essa função.

Nota:

Se dois elementos são considerados iguais, a ordem deles fica indefinida no array resultante.

Nota: Esta função atribui novas chaves aos elementos no array. Ela removerá todas as chaves existentes que possam ter sido atribuídas, em vez de apenas reordenar as chaves.

Parâmetros

array

The input array.

cmp_function

A função de comparação deve retornar um inteiro menor, igual ou maior que zero se o primeiro argumento for considerado respectivamente menor, igual, ou maior que o segundo.

Valor Retornado

Retorna true em caso de sucesso ou false em caso de falha.

Exemplos

Exemplo #1 Exemplo da 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");

foreach (
$a as $key => $value) {
echo
"$chave: $valor\n";
}
?>

O exemplo acima produzirá:

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

Nota:

Obviamente que nesse caso trivial a função sort() seria mais apropriada.

Exemplo #2 Exemplo de usort() usando um array multi-dimensional

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

$frutas[0]["fruta"] = "limoes";
$frutas[1]["fruta"] = "abacaxis";
$frutas[2]["fruta"] = "goiabas";

usort($frutas, "cmp");

while (list(
$chave, $valor) = each($frutas)) {
echo
"\$frutas[$chave]: " . $valor["fruta"] . "\n";
}
?>

Na ordenação de um array multi-dimensional, $a e $b contém referências para o primeiro índice do array.

O exemplo acima produzirá:

$fruits[0]: abacaxis
$fruits[1]: goiabas
$fruits[2]: limoes

Exemplo #3 Exemplo de usort() usando uma função membro de um objeto

<?php
class TestObj {
var
$name;

function
TestObj($name)
{
$this->name = $name;
}

/* Essa é a função estática de comparação */
static function cmp_obj($a, $b)
{
$al = strtolower($a->name);
$bl = strtolower($b->name);
if (
$al == $bl) {
return
0;
}
return (
$al > $bl) ? +1 : -1;
}
}

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

usort($a, array ("TestObj", "cmp_obj"));

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

O exemplo acima produzirá:

b
c
d

Veja Também

  • uasort() - Ordena um array utilizando uma função de comparação definida pelo usuário e mantendo as associações entre chaves e valores
  • uksort() - Ordena um array pelas chaves utilizando uma função de comparação definida pelo usuário.
  • sort() - Ordena um array em ordem ascendente
  • asort() - Ordena um array mantendo a associação entre índices e valores
  • arsort() - Ordena um array em ordem descrescente mantendo a associação entre índices e valores
  • ksort() - Ordena um array pelas chaves
  • natsort() - Ordena um array utilizando o algoritmo da "ordem natural"
  • rsort() - Ordena um array em ordem descrescente

add a note

User Contributed Notes 10 notes

up
13
Hayley Watson
10 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.

<?php
usort
($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

<?php
usort
($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
9
luke dot semerau at gmail dot com
14 years ago
If you need to use usort with a key in the calling method, I wrote this as a utility:
<?php

function 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));
    }
}

?>

<?php

require_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
10
mkr at binarywerks dot dk
20 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
5
sydney at totoche dot org
17 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
5
derek at luddite dot net
22 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
3
inigo dot grimbergen at gmail dot com
6 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;
    });
?>
returns
1
2
3
null
null
null
up
1
gus dot antoniassi at gmail dot com
3 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
1
chris at candm dot org dot uk
4 years ago
In case anyone is interested, comparative timings over 100000000 runs
Based on comparing integers (500 and 501)
Spaceship:4
()?: operator:10
Subtraction:2

Based on comparing floats (500.1 and 501.3) (caveats noted)
Spaceship:5
()?: operator:9
Subtraction:3

Based 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
3
andi_mclean at ntlworld dot com
11 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 Example
Slot 10 Example
Slot 2 Example

Should infact be
Slot 1 Example
Slot 2 Example
Slot 10 Example

<?php
function 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
3
bo at erichsen dot com
22 years ago
when using usort to refer to a function inside a class i have succesfully used:

<?php usort($myarray,array($this,"cmp")); ?>
To Top