PHP 7.0.6 Released

uasort

(PHP 4, PHP 5, PHP 7)

uasortSort an array with a user-defined comparison function and maintain index association

Description

bool uasort ( array &$array , callable $value_compare_func )

This function sorts an array such that array indices maintain their correlation with the array elements they are associated with, using a user-defined comparison function.

This is used mainly when sorting associative arrays where the actual element order is significant.

Note:

If two members compare as equal, their relative order in the sorted array is undefined.

Parameters

array

The input array.

value_compare_func

See usort() and uksort() for examples of user-defined comparison functions.

Return Values

Returns TRUE on success or FALSE on failure.

Examples

Example #1 Basic uasort() example

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

// Array to be sorted
$array = array('a' => 4'b' => 8'c' => -1'd' => -9'e' => 2'f' => 5'g' => 3'h' => -4);
print_r($array);

// Sort and print the resulting array
uasort($array'cmp');
print_r($array);
?>

The above example will output:

Array
(
    [a] => 4
    [b] => 8
    [c] => -1
    [d] => -9
    [e] => 2
    [f] => 5
    [g] => 3
    [h] => -4
)
Array
(
    [d] => -9
    [h] => -4
    [c] => -1
    [e] => 2
    [g] => 3
    [a] => 4
    [f] => 5
    [b] => 8
)

See Also

User Contributed Notes

magikMaker
5 years ago
a quick reminder on the syntax if you want to use uasort in a Class or Object:

<?php

// procedural:
uasort($collection, 'my_sort_function');

// Object Oriented
uasort($collection, array($this, 'mySortMethod'));

// Objet Oriented with static method
uasort($collection, array('self', 'myStaticSortMethod'));

?>
php at clement dot hk
2 years ago
If you want to keep the order when two members compare as equal, use this.
<?php

function stable_uasort(&$array, $cmp_function) {
    if(
count($array) < 2) {
        return;
    }
   
$halfway = count($array) / 2;
   
$array1 = array_slice($array, 0, $halfway, TRUE);
   
$array2 = array_slice($array, $halfway, NULL, TRUE);

   
stable_uasort($array1, $cmp_function);
   
stable_uasort($array2, $cmp_function);
    if(
call_user_func($cmp_function, end($array1), reset($array2)) < 1) {
       
$array = $array1 + $array2;
        return;
    }
   
$array = array();
   
reset($array1);
   
reset($array2);
    while(
current($array1) && current($array2)) {
        if(
call_user_func($cmp_function, current($array1), current($array2)) < 1) {
           
$array[key($array1)] = current($array1);
           
next($array1);
        } else {
           
$array[key($array2)] = current($array2);
           
next($array2);
        }
    }
    while(
current($array1)) {
       
$array[key($array1)] = current($array1);
       
next($array1);
    }
    while(
current($array2)) {
       
$array[key($array2)] = current($array2);
       
next($array2);
    }
    return;
}

function
cmp($a, $b) {
    if(
$a['n'] == $b['n']) {
        return
0;
    }
    return (
$a['n'] > $b['n']) ? -1 : 1;
}

$a = $b = array(
   
'a' => array("l" => "A", "n" => 1),
   
'b' => array("l" => "B", "n" => 2),
   
'c' => array("l" => "C", "n" => 1),
   
'd' => array("l" => "D", "n" => 2),
   
'e' => array("l" => "E", "n" => 2),
);

uasort($a, 'cmp');
print_r($a);

stable_uasort($b, 'cmp');
print_r($b);
?>

returns

Array
(
    [e] => Array
        (
            [l] => E
            [n] => 2
        )

    [b] => Array
        (
            [l] => B
            [n] => 2
        )

    [d] => Array
        (
            [l] => D
            [n] => 2
        )

    [c] => Array
        (
            [l] => C
            [n] => 1
        )

    [a] => Array
        (
            [l] => A
            [n] => 1
        )

)
Array
(
    [b] => Array
        (
            [l] => B
            [n] => 2
        )

    [d] => Array
        (
            [l] => D
            [n] => 2
        )

    [e] => Array
        (
            [l] => E
            [n] => 2
        )

    [a] => Array
        (
            [l] => A
            [n] => 1
        )

    [c] => Array
        (
            [l] => C
            [n] => 1
        )
)

https://bugs.php.net/bug.php?id=53341
stilgar_cpsNOSPAM at zipmail dot NOSPAMcom dot br
14 years ago
Use example:

$array[0]['Fator1']=7;
$array[0]['Fator2']="Name";
$array[1]['Fator1']=5;
$array[1]['Fator2']="Name";
$array[2]['Fator1']=7;
$array[2]['Fator2']="NameDiferente";
.....

We want to order by Fator1, then Fator2, then:

function Compare($ar1, $ar2)
{
   if ($ar1['Fator1']<$ar2['Fator1'])
      return -1;
   else if ($ar1['Fator1']>$ar2['Fator1'])
      return 1;
   if ($ar1['Fator2']<$ar2['Fator2'])
      return -1;
   else if ($ar1['Fator2']>$ar2['Fator2'])
      return 1;
   return 0;
}

To sort now, we use:

uasort($array, 'Compare');
iborodikhin at gmail dot com
3 years ago
To shuffle assoc array preserving keys just do this:
<?php uasort(
   
$array,
    function (
$a, $b) {
        return
mt_rand(0, 1) > 0 ? 1 : -1;
    }
);
?>
phire_sk
5 years ago
I tried using some of the previous built multisorts, but they weren't working as expected.

So, I made my own Class, and it seems to work wonderfully.

Here is the code:

<?php
/************************************
*    Allows sorting multi-dimensional
*    arrays by a specific key and in
*    asc or desc order
**/
class multiSort
{
    var
$key;    //key in your array

    //runs the sort, and returns sorted array
   
function run ($myarray, $key_to_sort, $type_of_sort = '')
    {
       
$this->key = $key_to_sort;
       
        if (
$type_of_sort == 'desc')
           
uasort($myarray, array($this, 'myreverse_compare'));
        else
           
uasort($myarray, array($this, 'mycompare'));
           
        return
$myarray;
    }
   
   
//for ascending order
   
function mycompare($x, $y)
    {
        if (
$x[$this->key] == $y[$this->key] )
            return
0;
        else if (
$x[$this->key] < $y[$this->key] )
            return -
1;
        else
            return
1;
    }
   
   
//for descending order
   
function myreverse_compare($x, $y)
    {
        if (
$x[$this->key] == $y[$this->key] )
            return
0;
        else if (
$x[$this->key] > $y[$this->key] )
            return -
1;
        else
            return
1;
    }
}
?>
yannick dot battail at gmail dot com
5 years ago
An Example using anonymous function.
Anonymous functions make some time the code easier to understand.
<?php
$fruits
= array('Orange9','Orange11','Orange10','Orange6','Orange15');
uasort ( $fruits , function ($a, $b) {
            return
strnatcmp($a,$b); // or other function/code
       
}
    );
print_r($fruits);
?>
returns
Array
(
    [3] => Orange6
    [0] => Orange9
    [2] => Orange10
    [1] => Orange11
    [4] => Orange15
)
php arobase kochira period com
7 years ago
Difference between uasort() and usort(), the missing example ...

<?php
  $arr
= array ( 10 => array('id' => 'dix''aa' => '1010'),
               
100 => array('id' => 'cent', 'aa' => '100100'),
                 
2 => array('id' => 'deux', 'aa' => '22'),
                 
7 => array('id' => 'sept', 'aa' => '77'));

 
// id sorting
 
function so ($a, $b) { return (strcmp ($a['id'],$b['id']));    }
?>

*** uasort($arr, 'so') output:

<?php Array (
    [
100] => Array
        (
            [
id] => cent
           
[aa] => 100100
       
)

    [
2] => Array
        (
            [
id] => deux
           
[aa] => 22
       
)

    [
10] => Array
        (
            [
id] => dix
           
[aa] => 1010
       
)

    [
7] => Array
        (
            [
id] => sept
           
[aa] => 77
       
))?>

*** usort($arr, 'so') output:

<?php Array (
    [
0] => Array
        (
            [
id] => cent
           
[aa] => 100100
       
)

    [
1] => Array
        (
            [
id] => deux
           
[aa] => 22
       
)

    [
2] => Array
        (
            [
id] => dix
           
[aa] => 1010
       
)

    [
3] => Array
        (
            [
id] => sept
           
[aa] => 77
       
))?>
Said Dashuk
4 years ago
My simple and effective solution for sort multi-dimensional array by any key:

<?php
function sort_by_key ($arr,$key) {
    global
$key2sort;
   
$key2sort = $key;
   
uasort($arr, 'sbk');
    return (
$arr);
}
function
sbk ($a, $b) {global $key2sort; return (strcasecmp ($a[$key2sort],$b[$key2sort]));}
?>
php at eden2 dot com
12 years ago
Is it just me, or are the examples below misleading, and actually demonstrating situations that would be more appropriate for usort()?

After trying to make sense of the uasort() description, it sounds like it's more for sorting a 1D array like this:

"john" => "$23.12"
"tim" => "$6.50"
"bob" => "$18.54"

and getting back:

"tim" => "$6.50"
"bob" => "$18.54"
"john" => $23.12"

(assuming, of course, that your sort function is lopping off the $ and evaluating as a number -- which would complicate the use of asort() ;)
Yves
5 years ago
Took me some time to figure that out:
the user function must return an *integer*, if you return a float, you may not get the expected result.

<?php
  $a
= ('a' => 0.9, 'b' => 0.7, 'c' => 0.8);

  function
sorting($a, $b) { return $a - $b; }

 
// The function above will not =work, you have to

 
function sorting($a, $b)
  {
  
$d = $a = $b;
    return
$d < 0 ? -1 : ($d > 0 ? 1 : 0);
  }
?>
Anonymous
2 years ago
//this fix the problem of if any of these sort functions evaluates two members as equal then the order is undefined (the sorting is not stable).

$pos=0;
foreach($values as $k => $v)
  $tosort[$k]=array($v,$pos++);
uasort($tosort,function($a, $b) {
  if($a[0] != $b[0])return ($a[0] < $b[0]) ? -1 : 1;
    return ($a[1] < $b[1]) ? -1 : 1;}
);
foreach($tosort as $k => $v)
  $values[$k]=$v[0];
temper26 at yandex dot ru
3 months ago
сортировка массива с одинаковыми значениями

$sortPos = 0;
foreach($arResult['ITEMS'] as $k=>&$arItem) {
    $arItem['SORT_POS'] = ++$sortPos;
}
unset($arItem);

uasort($arResult['ITEMS'],function($a,$b){
    if ($a['SORT']==$b['SORT']) {
        return ($a['SORT_POS'] < $b['SORT_POS']) ? -1 : 1;
    }
    return ($a['SORT']<$b['SORT']) ? -1 : 1;
});
stephan dot hoyer at netresearch dot de
5 years ago
To sort string containing Umlauts you can use this callback function:

<?php
   
function sortWUmlauts($s1, $s2)
    {
       
$search = array('Ä','Ö','Ü','ß');
       
$replace = array('A','O','U','s');
        return
strcmp(
          
str_ireplace($search, $replace, $s1),
          
str_ireplace($search, $replace, $s2)
           );
    }
?>

simply call:

<?php uasort($array, 'sortWUmlauts'); ?>
paul at webtop-designs dot com
6 years ago
Just expanding on php arobase kochira period com's method:

If you are looking to sort a multi-D array by a specific column and have entries in both upper and lower case, simply drop the entries to lowercase before doing the strcmp.

<?php
$dirs
= array(
  array(
'name' => 'First Folder', 'path' => 'sompath'),
  array(
'name' => 'second folder', 'path' => 'sompath2'),
  array(
'name' => 'Third Folder', 'path' => 'sompath3')
);

function
so($a, $b) {
    return (
strcmp (strtolower($a['name']), strtolower($b['name'])));
}
?>
naholyr at yahoo dot fr
13 years ago
You can sort a multidimensionnal array by any of its key with this function:

function multi_sort($array, $key)
{
  $cmp_val="((\$a['$key']>\$b['$key'])?1:
    ((\$a['$key']==\$b['$key'])?0:-1))";
  $cmp=create_function('$a, $b', "return $body;");
  uasort($array, $cmp);
  return $array;
}

example:
$myarray = array(
  array("name"=>"kernighan", "language"=>"c"),
  array("name"=>"lerdorf", "language"=>"php"),
  array("name"=>"Stroustrup", "language"=>"c++"),
  array("name"=>"Gosling", "language"=>"java")
);

multi_sort($myarray, "name") returns:
name=Gosling    language=java
name=Kernighan    language=c
name=Lerdorf    language=php
name=Stroustrup    language=c++
dholmes at jccc d0t net
13 years ago
Here is a little sort function that actually uses a dynamic callback for usort to do it's thing.

It assumes your data is in the form of:
    $data = array(
            array('ID'=>'6','LAST'=>'Holmes','FIRST'=>'Dan'),
            array('ID'=>'1234','LAST'=>'Smith','FIRST'=>'Agent K'),
            array('ID'=>'2','LAST'=>'Smith','FIRST'=>'Agent J'),
            array('ID'=>'4','LAST'=>'Barney','FIRST'=>'Bob'));

Now, you want to sort on one or more cols, don't you? 

masort($data, 'LAST,FIRST');
or
masort($data,array('FIRST','ID'));

Of course you could add a bunch to it (like numeric comparison if appropriate, desc/asc, etc) but it works for me.

function masort(&$data, $sortby){
    if(is_array($sortby)){
        $sortby = join(',',$sortby);
    }

    uasort($data,create_function('$a,$b','$skeys = split(\',\',\''.$sortby.'\');
        foreach($skeys as $key){
            if( ($c = strcasecmp($a[$key],$b[$key])) != 0 ){
                return($c);
            }
        }
        return($c); '));
}
Notice that I am splitting the string in the comparison function? While this is certainly slower, it was the only way I would find to "pass" and "array".  If anyone has a better way, please suggest.  Then inside, we (string) compare the values only moving to the next key if the values are the same...and so on, and so on.
clem at fragment dot at
4 years ago
for a simple case insensitive compare you can use this (php >= 5.3):

<?php
$greetings
= array('howdy', 'Hey', 'aloha he');

uasort($a, function($a, $b){ return strcasecmp($a, $b); });

//$a == array('aloha he', 'howdy', 'Hey');
?>
david [__at__] castlelaing.com
11 years ago
WARNING:-Regarding remmy.cjb.net (22-Oct-2003 05:57) mutisort() function:

Sorting by floating point numbers doesn't work in the current function. Use the modified version below if you want to sort by a floating point column.

<?php
// Based on the other notes given before.
// Sorts an array (you know the kind) by key
// and by the comparison operator you prefer.

// Note that instead of most important criteron first, it's
// least important criterion first.

// The default sort order is ascending, and the default sort
// type is strnatcmp.

// function multisort($array[, $key, $order, $type]...)
function multisort($array)
{
   for(
$i = 1; $i < func_num_args(); $i += 3)
   {
      
$key = func_get_arg($i);
       if (
is_string($key)) $key = '"'.$key.'"';
     
      
$order = true;
       if(
$i + 1 < func_num_args())
          
$order = func_get_arg($i + 1);
     
      
$type = 0;
       if(
$i + 2 < func_num_args())
          
$type = func_get_arg($i + 2);

       switch(
$type)
       {
           case
1: // Case insensitive natural.
              
$t = 'strcasecmp($a[' . $key . '], $b[' . $key . '])';
               break;
           case
2: // Numeric.
              
$t = '($a[' . $key . '] == $b[' . $key . ']) ? 0:(($a[' . $key . '] < $b[' . $key . ']) ? -1 : 1)';
               break;
           case
3: // Case sensitive string.
              
$t = 'strcmp($a[' . $key . '], $b[' . $key . '])';
               break;
           case
4: // Case insensitive string.
              
$t = 'strcasecmp($a[' . $key . '], $b[' . $key . '])';
               break;
           default:
// Case sensitive natural.
              
$t = 'strnatcmp($a[' . $key . '], $b[' . $key . '])';
               break;
       }
       echo
$t;
      
usort($array, create_function('$a, $b', '; return ' . ($order ? '' : '-') . '(' . $t . ');'));
   }
   return
$array;
}
?>
To Top