usort


php128 apg

SORT an ARRAY using an user-defined comparison function.





This function returns TRUE on success or FALSE on failure.

This function will sort an array by its values using a user-supplied comparison function.

If the array you wish to sort needs to be sorted by some non-trivial criteria, you should use this function.

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

This function assigns new keys to the elements in $array.

It will remove any existing keys that may have been assigned, rather than just reordering the keys.

The $value_compare_func, comparison function must return an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second.

Note that before PHP 7.0.0 this integer had to be in the range from -2147483648 to 2147483647.



<?php

bool usort 
arr &$array , callable $value_compare_func )


where,

&
$array The input ARRAY

$value_compare_func The comparisson function

?> 

&$array


The input ARRAY.



$value_compare_func


An user-defined function.



<?php

int callback 
mix $amix $b )


where,

$a First value to operate this function


$b Second value to operate this function

?> 

 CAUTION 


Returning non-integer values from the comparison function, such as float, will result in an internal cast to integer of the callback's return value.

So values such as 0.99 and 0.1 will both be cast to an integer value of 0, which will compare such values as equal.



  1 EXERCISE   

<?php

function recc01 $i$j )
{
return 
$i%$j;
}

$arr01u = [2818379];

echo 
'The given ARRAY:<br><pre>';
var_dump($arr01u);
echo 
'</pre>';

echo 
'<br>';

usort($arr01u'recc01');

echo 
'The SORTED ARRAY:<br><pre>';
var_dump($arr01u);
echo 
'</pre>';

?> 

 RESULT   

The given ARRAY:
array(6) {
[0]=>
int(2)
[1]=>
int(8)
[2]=>
int(18)
[3]=>
int(3)
[4]=>
int(7)
[5]=>
int(9
)

The SORTED ARRAY:
array(6) {
[0]=>
int(7)
[1]=>
int(18)
[2]=>
int(9)
[3]=>
int(3)
[4]=>
int(8)
[5]=>
int(2)
)


  2 EXERCISE   

<?php

function recc02 $i$j )
{
return 
$j%$i;
}

$arr02u = [2818379];

echo 
'The given ARRAY:<br><pre>';
var_dump($arr02u);
echo 
'</pre>';

echo 
'<br>';

usort($arr02u'recc02');

echo 
'The SORTED ARRAY:<br><pre>';
var_dump($arr02u);
echo 
'</pre>';

?> 

 RESULT   

The given ARRAY:
array(6) {
[0]=>
int(2)
[1]=>
int(8)
[2]=>
int(18)
[3]=>
int(3)
[4]=>
int(7)
[5]=>
int(9
)

The SORTED ARRAY:
array(6) {
[0]=>
int(7)
[1]=>
int(3)
[2]=>
int(9)
[3]=>
int(2)
[4]=>
int(18)
[5]=>
int(8)
)


  3 EXERCISE   

<?php

function recc03 $i$j )
{
return 
$j;
}

$arr03u = [ 
"Countries" => [ 'BRA' => "Brasil"
                        
'POR' => "Portugal"'JPN' => "Japan" ], 
"Continents" =>  ['SA' => "South America"
                          
'EU' => "Europe"'AS' => "Asia"]
          ]; 

echo 
'The given ARRAY:<br><pre>';
var_dump($arr03u);
echo 
'</pre>';

echo 
'<br>';

usort($arr03u'recc03');

echo 
'The SORTED ARRAY:<br><pre>';
var_dump($arr03u);
echo 
'</pre>';

?> 

 RESULT   

The given ARRAY:
array(2) {
["Countries"]=>
array(3) {
["BRA"]=>
string(6) "Brasil"
["POR"]=>
string(8) "Portugal"
["JPN"]=>
string(5) "Japan"
}
["Continents"]=>
array(3) {
["SA"]=>
string(13) "South America"
["EU"]=>
string(6) "Europe"
["AS"]=>
string(4) "Asia"
}
}

The SORTED ARRAY:
array(2) {
[0]=>
array(3) {
["SA"]=>
string(13) "South America"
["EU"]=>
string(6) "Europe"
["AS"]=>
string(4) "Asia"
}
[1]=>
array(3) {
["BRA"]=>
string(6) "Brasil"
["POR"]=>
string(8) "Portugal"
["JPN"]=>
string(5) "Japan"
}
}


  4 EXERCISE   

<?php

function recc04 $i$j )
{
echo 
$j '<br><br>' $i;
}

$arr04u = [ 
"english" => 'unconstitutional'
"portuguese" =>  'inconstitucional']; 

echo 
'The given ARRAY:<br><pre>';
var_dump($arr04u);

echo 
'</pre><br>The SORTED ARRAY:<br><br>';

usort($arr04u'recc04');

?> 

 RESULT   

The given ARRAY:
array(2) {
["english"]=>
string(16) "unconstitutional"
["portuguese"]=>
string(16) "inconstitucional"
}

The SORTED ARRAY:
inconstitucional

unconstitutional


  5 EXERCISE   

<?php

function recc05($i$j)
{
return 
strcmp($i[0], $j[0]);
}

$colors[0][0] = "RED";
$colors[1][0] = "GREEN";
$colors[2][0] = "BLUE";

usort($colors"recc05");

echo 
'<pre>';
var_dump($colors);
echo 
'</pre>';

$c count($colors) - 1;

for(
$x 0$x <= $c$x++)
{
    echo 
$x ' => ' $colors[$x][0] . '<br>';
}

?>

 RESULT   

array(3) {
[0]=>
array(1) {
[0]=>
string(4) "BLUE"
}
[1]=>
array(1) {
[0]=>
string(5) "GREEN"
}
[2]=>
array(1) {
[0]=>
string(3) "RED"
}
}

or

0 => BLUE
1 => GREEN
2 => RED


  6 EXERCISE   

<?php
/*
 * Test basic functionality of usort() 
 * with indexed and associative arrays
 */

echo "Testing usort() : basic functionality.";

function 
cmp($value1$value2)
{
  if(
$value1 == $value2) {
    return 
0;
  }
  else if(
$value1 $value2) {
    return 
1;
  }
  else
    return -
1;
}

// Int array with default keys
$int_values = array(1893267);

echo 
"<br><br>Numeric array with default keys:<br>";
var_dumpusort($int_values'cmp') );
echo 
'<br><br>';
var_dump($int_values);

// String array with default keys
$string_values = array("This""is"'a'"test");

echo 
"<br><br>String array with default keys:<br>";
var_dumpusort($string_values'cmp') );
echo 
'<br><br>';
var_dump($string_values);

// Associative array with numeric keys
$numeric_key_arg = array(1=> 1=> 2=> 7=> 4=> 9);

echo 
"<br><br>Associative array with numeric keys:<br>";
var_dumpusort($numeric_key_arg'cmp') );
echo 
'<br><br>';
var_dump($numeric_key_arg);

// Associative array with string keys
$string_key_arg = array('one' => 4'two' => 2'three' => 1'four' => 10);

echo 
"<br><br>Associative array with string keys:<br>";
var_dumpusort($string_key_arg'cmp') );
echo 
'<br><br>';
var_dump($string_key_arg);

?>

  7 EXERCISE   

<?php

$array 
range(010000);
usort($array, function($a$b) {
    
// Everything is equal!
    
return 0;
});
var_dump($array === range(010000));

?>

 RESULT   

Run this exercise on different versions of PHP to see the differences in the results.

  8 EXERCISE   

<?php
/*
 * Pass an array with duplicate keys 
 * and values to usort() to test behaviour
 */

echo "Testing usort() : usage variation.";

function 
cmp($value1$value2)
{
  if(
$value1 == $value2) {
    return 
0;
  }
  else if(
$value1 $value2) {
    return 
1;
  }
  else
    return -
1;
}

// Array with duplicate string 
// and integer keys and values
$array_arg = [ => 2"a" => 8"d" => 9,
                   
=> 3,     => 2,   "o" => 6,
                   
"z" => -99=> 1,   "z" => ];

echo 
"<br><br>Array with duplicate keys:<br>";
var_dumpusort($array_arg'cmp') );
echo 
'<br><br>';
var_dump($array_arg);

// Array with default and assigned keys
$array_arg = [ => "Banana"=> "Mango"
                      
"Orange"=> "Apple""Pineapple" ];

echo 
"<br><br>Array with default/assigned keys:<br>";
var_dumpusort($array_arg'cmp') );
echo 
'<br><br>';
var_dump($array_arg);

?>

  9 EXERCISE   

<?php

/*
 * Pass an array with different 
 * data types as keys to usort() 
 * to test how it is re-ordered
 */

echo "Testing usort() : usage variation.";

function 
cmp_function($value1$value2)
{
  if(
$value1 == $value2) {
    return 
0;
  }
  else if(
$value1 $value2) {
    return -
1;
  }
  else {
    return 
1;
  }
}

// different heredoc strings

// single line heredoc string
$simple_heredoc = <<<EOT2
simple
EOT2;

// multiline heredoc string
$multiline_heredoc = <<<EOT3
multiline heredoc with 123
and speci@! ch@r..\ncheck\talso
EOT3;

$array_arg = array(
  
// numeric keys
  
-=> 9,
  
8.9 => 8,
  
012 => 7,
  
0x34 => 6,

  
// string keys
  
'key' => 5,  //single quoted key
  
"two" => 4,  //double quoted key
  
" " => 0,  // space as key

  // bool keys
  
TRUE => 100,
  
FALSE => 25,

  
// null keys
  
NULL => 35,

  
// binary key
  
"a".chr(0)."b" => 45,
  
b"binary" => 30,

  
//heredoc keys
  
$simple_heredoc => 75,
  
$multiline_heredoc => 200,

  
// default key
  
1,
);

var_dumpusort($array_arg'cmp_function') );
echo 
"<br><br>Sorted array after usort() function call:<br><pre>";
var_dump($array_arg);
echo 
'</pre>';

?>

  10 EXERCISE   

<?php

/*
 * Pass arrays of numeric data to usort() 
 * to test how it is re-ordered
 */

echo "Testing usort() : usage variation.";

function 
cmp_function($value1$value2)
{
  if(
$value1 == $value2) {
    return 
0;
  }
  else if(
$value1 $value2) {
    return 
1;
  }
  else {
    return -
1;
  }
}

// Int array
$int_values = [ => 3,   => 2,   => 100,
                       
=> 150=> 25,  => 350,
                       
=> 0,   => -3,  => -1200 ];

echo 
"<br><br>Sorting Integer array:<br>";
var_dumpusort($int_values'cmp_function') );
echo 
"<br><br>";
var_dump($int_values);

// Octal array
$octal_values = [ => 056=> 023,  => 00,
                          
=> 015=> -045=> 01,  
                          
=> -07 ];

echo 
"<br><br>Sorting Octal array:<br>";
var_dumpusort($octal_values'cmp_function') );
echo 
"<br><br>";
var_dump($octal_values);

// Hexadecimal array
$hex_values = [ => 0xAE,  => 0x2B
                        
=> 0X10=> -0xCF
                        
=> 0X12=> -0XF2 ];

echo 
"<br><br>Sorting Hex array:<br>";
var_dumpusort($hex_values'cmp_function') );
echo 
"<br><br>";
var_dump($hex_values);

// Float array
$float_values = [ => 10.2
                          
=> 2.4
                          
=> -3.4,
                          
=> 0,    => 0.5
                          
=> 7.3e3
                          
=> -9.34E-2 ];

echo 
"<br><br>Sorting Float array:<br>";
var_dumpusort($float_values'cmp_function') );
echo 
"<br><br>";
var_dump($float_values);

// empty array
$empty_array = array();

echo 
"<br><br>Sorting empty array:<br>";
var_dumpusort($empty_array'cmp_function') );
echo 
"<br><br>";
var_dump($empty_array);

?>

  11 EXERCISE   

<?php

/*
 * Pass arrays of string data to usort() 
 * to test how it is re-ordered
 */

echo "Testing usort() : usage variation.";

function 
cmp_function($value1$value2)
{
  if(
$value1 == $value2) {
    return 
0;
  }
  else if(
$value1 $value2) {
    return 
1;
  }
  else {
    return -
1;
  }
}

// Different heredoc strings to be sorted
$empty_heredoc =<<<EOT
EOT;

$simple_heredoc1 =<<<EOT
Heredoc
EOT;

$simple_heredoc2 =<<<EOT
HEREDOC
EOT;

$multiline_heredoc =<<<EOT
heredoc string\twith!@# and 123
Test this!!!
EOT;

// Single quoted strings
$single_quoted_values = array(
  
=> ' ',  => 'test'=> 'Hello'=> 'HELLO',
  
=> '',   => '\t',   => '0',     => '123Hello',
  
=> '\''10 => '@#$%'
);

echo 
"<br><br>Sorting Single Quoted String values:<br>";
var_dumpusort($single_quoted_values'cmp_function') );
echo 
"<br><br>";
var_dump($single_quoted_values);

// Double quoted strings
$double_quoted_values = array(
  
=> " ",  => "test"=> "Hello"=> "HELLO",
  
=> "",   => "\t",   => "0",     => "123Hello",
  
=> "\""10 => "@#$%"
);

echo 
"<br><br>Sorting Double Quoted String values:<br>";
var_dumpusort($double_quoted_values'cmp_function') );
echo 
"<br><br>";
var_dump($double_quoted_values);

// Heredoc strings
$heredoc_values = array(=> $empty_heredoc,   => $simple_heredoc1,
                        
=> $simple_heredoc2=> $multiline_heredoc);

echo 
"<br><br>Sorting Heredoc String values:<br>";
var_dumpusort($heredoc_values'cmp_function') );
echo 
"<br><br>";
var_dump($heredoc_values);
?>

  12 EXERCISE   

<?php

/*
 * Pass a multi-dimensional array as 
 * $array_arg argument to usort()
 * to test how array is re-ordered
 */

echo "Testing usort() : usage variation.";

function 
cmp_function($value1$value2)
{
  if(
$value1 == $value2) {
    return 
0;
  }
  else if(
$value1 $value2) {
    return 
1;
  }
  else {
    return -
1;
  }
}

$array_args = array(
  
=> array(210, -1),
  
=> array(100),
  
=> array(),
  
=> array(0),
  
=> array(-1),
  
=> array(-93454020),
  
=> array(''),
  
=> array("apple""Apple""APPLE""aPPle""aPpLe")
);

$temp_array $array_args;

echo 
"<br><br>Pass usort() a two-dimensional array:<br>";
// sorting array_arg as whole array
var_dumpusort($temp_array'cmp_function') );

echo 
"<br><br>Array after call to usort():<br>";
var_dump($temp_array);

echo 
"<br><br>Pass usort() a sub-array:<br>";
var_dumpusort($array_args[5], 'cmp_function') );

echo 
"<br><br>Array after call to usort():<br>";
var_dump($array_args[5]);
?>

  13 EXERCISE   

<?php
/*
 * Pass an anonymous comparison 
 * function as $cmp_function argument 
 * to test behaviour()
 */

echo "Testing usort() : usage variation.";

$cmp_function = function($value1$value2) {
    if (
$value1 == $value2) { return 0; }
    else if (
$value1 $value2) { return 1; }
    else { return -
1; }
};

$array_arg = array(=> 100
                              
=> 3
                              
=> -70
                              
=> 24
                              
=> 90);

echo 
"<br><br>Anonymous 'cmp_function' 
                     with parameters passed by value:<br>"
;
var_dumpusort($array_arg$cmp_function) );
echo 
"<br><br>";
var_dump($array_arg);

$array_arg = array("b" => "Banana"
                              
"m" => "Mango"
                              
"a" => "Apple"
                              
"p" => "Pineapple");

$cmp_function = function(&$value1, &$value2) {
    if (
$value1 == $value2) { return 0; }
    else if (
$value1 $value2) { return 1; }
    else { return -
1; }
};

echo 
"<br><br>Anonymous 'cmp_function' 
                       with parameters passed by reference:<br>"
;
var_dumpusort($array_arg$cmp_function) );
echo 
"<br><br>";
var_dump($array_arg);

?>

  14 EXERCISE   

<?php

/*
 * Test usort() when comparison function is:
 * 1. a built in comparison function
 * 2. a language construct
 */

echo "Testing usort() : usage variation.";

// Initializing variables
$array_arg = [ "b" => "Banana"
                       
"m" => "Mango"
                       
"a" => "apple",
                       
"p" => "Pineapple"
                       
"o" => "orange"];

// Testing library functions as comparison function
echo "<br><br>Testing usort() 
                  with built-in 
                  'cmp_function': strcasecmp():<br>"
;
$temp_array1 $array_arg;
var_dumpusort($temp_array1'strcasecmp') );
echo 
"<br><br>";
var_dump($temp_array1);

echo 
"<br><br>Testing usort() 
                    with built-in 
                    'cmp_function': strcmp():<br>"
;
$temp_array2 $array_arg;
var_dumpusort($temp_array2'strcmp') );
echo 
"<br><br>";
var_dump($temp_array2);

?>

  15 EXERCISE   

<?php

/*
 * Pass an array of referenced 
 * variables as $array_arg to 
 * test behaviour
 */

echo "Testing usort() : usage variation.";

function 
cmp_function($value1$value2)
{
  if(
$value1 == $value2) {
    return 
0;
  }
  else if(
$value1 $value2) {
    return 
1;
  }
  else {
    return -
1;
  }
}

// different variables which are used 
// as elements of $array_arg
$value1 = -5;
$value2 100;
$value3 0;
$value4 = &$value1;

// array_args an array containing 
// elements with reference variables
$array_arg = [
  
=> 10,
  
=> &$value4,
  
=> &$value2,
  
=> 200,
  
=> &$value3,
];

echo 
"<br><br>Sorting \$array_arg 
                     containing different
                               references:<br>"
;
var_dumpusort($array_arg'cmp_function') );
echo 
"<br><br>";
var_dump($array_arg);

?>

  16 EXERCISE   

<?php

set_error_handler
(function($code$message) {
  
var_dump($code$message);
});

$comparatornull;
$list= [1423, -1];
usort($list, function($a$b) use ($comparator) {
  try {
      return 
$comparator->compare($a$b);
  } catch (
Error $e) {
      
var_dump($e->getCode(), $e->getMessage());
      echo 
"<br><br>";
      return 
0;
  }
});
var_dump($list);

?>

  17 EXERCISE   

<?php

/*
 * Pass an array of objects which 
 * have a different number of properties
 * to test behaviour of usort()
 */

echo "Testing usort() : object functionality.<br>";

function 
simple_cmp($value1$value2)
{
    if(
$value1 == $value2) {
        return 
0;
    }
    else if(
$value1 $value2) {
        return 
1;
    }
    else
    return -
1;
}

// comparison function for SimpleClass2 
// objects which has more than one member
function multiple_cmp($value1$value2)
{
    if(
$value1->getValue() == $value2->getValue())
    return 
0;
    else if(
$value1->getValue() > $value2->getValue())
    return 
1;
    else
    return -
1;
}

// Simple class with single property
class SimpleClass1
{
    private 
$int_value;

    public function 
__construct($value) {
        
$this->int_value $value;
    }
}

// Simple class with more than one property
class SimpleClass2
{
    private 
$int_value;
    protected 
$float_value;
    public 
$string_value;
    public function 
__construct($int$float$str) {
        
$this->int_value $int;
        
$this->float_value $float;
        
$this->string_value $str;
    }
    public function 
getValue() {
        return 
$this->int_value;
    }
}

// array of SimpleClass objects with only one property
$array_arg = array(
=> new SimpleClass1(10),
=> new SimpleClass1(1),
=> new SimpleClass1(100),
=> new SimpleClass1(50)
);
echo 
'<br>';
var_dumpusort($array_arg'simple_cmp') );
echo 
'<br><pre>';
var_dump($array_arg);
echo 
'</pre>';

// array of SimpleClass objects having more than one properties
$array_arg = array(
=> new SimpleClass2(23.4"mango"),
=> new SimpleClass2(101.2"apple"),
=> new SimpleClass2(52.5"orange"),
);
echo 
'<br>';
var_dumpusort($array_arg'multiple_cmp') );
echo 
'<br><pre>';
var_dump($array_arg);
echo 
'</pre>';

?>

  18 EXERCISE   

<?php

/*
 * Pass an array of objects which are either:
 * 1. Empty
 * 2. Static
 * 2. Inherited
 * to test behaviour of usort()
 */

echo "Testing usort() : object functionality.";

function 
cmp_function($value1$value2)
{
  if(
$value1 == $value2) {
    return 
0;
  }
  else if(
$value1 $value2) {
    return 
1;
  }
  else
    return -
1;
}

// Class without any member
class EmptyClass
{
}

// Class with static member
class StaticClass
{
  public static 
$static_value;
  public function 
__construct($value) {
    
StaticClass::$static_value $value;
  }
}

// Abstract class
abstract class AbstractClass
{
  public 
$pub_value;
  public abstract function 
abstractMethod();
}

// Child class extending abstract class
class ChildClass extends AbstractClass
{
  public 
$child_value 100;
  public function 
abstractMethod() {
    
$pub_value 5;
  }
  public function 
__construct($value) {
    
$this->child_value $value;
  }
}

// Testing uasort with StaticClass 
// objects as elements of 'array_arg'
echo "<br><br>Testing usort() with StaticClass objects:<br>";
$array_arg = array(
  
=> new StaticClass(20),
  
=> new StaticClass(50),
  
=> new StaticClass(15),
  
=> new StaticClass(70),
);
echo 
'<br>';
var_dumpusort($array_arg'cmp_function') );
echo 
'<br><pre>';
var_dump($array_arg);
echo 
'</pre>';

// Testing uasort with EmptyClass objects 
// as elements of 'array_arg'
echo "<br><br>Testing usort() with EmptyClass objects:<br>";
$array_arg = array(
  
=> new EmptyClass(),
  
=> new EmptyClass(),
  
=> new EmptyClass(),
  
=> new EmptyClass(),
);
echo 
'<br>';
var_dumpusort($array_arg'cmp_function') );
echo 
'<br><pre>';
var_dump($array_arg);
echo 
'</pre>';

// Testing uasort with ChildClass objects 
// as elements of 'array_arg'
echo "<br><br>Testing usort() with ChildClass objects:<br>";
$array_arg = array(
  
=> new ChildClass(20),
  
=> new ChildClass(500),
  
=> new ChildClass(15),
  
=> new ChildClass(700),
);
echo 
'<br>';
var_dumpusort($array_arg'cmp_function') );
echo 
'<br><pre>';
var_dump($array_arg);
echo 
'</pre>';

?>