uksort
Sorts array in place by keys using a user-supplied comparison function to determine the order.
Note:
If two members compare as equal, they retain their original order. Prior to PHP 8.0.0, their relative order in the sorted array was undefined.
Note:
Resets array’s internal pointer to the first element.
Parameters
The 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.
Returning non-integer values from the comparison function, such as float , will result in an internal cast to int 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.
Return Values
Always returns true .
Changelog
Version | Description |
---|---|
8.2.0 | The return type is true now; previously, it was bool . |
8.0.0 | If callback expects a parameter to be passed by reference, this function will now emit an E_WARNING . |
Examples
Example #1 uksort() example
function cmp ( $a , $b )
$a = preg_replace ( ‘@^(a|an|the) @’ , » , $a );
$b = preg_replace ( ‘@^(a|an|the) @’ , » , $b );
return strcasecmp ( $a , $b );
>
?php
$a = array( «John» => 1 , «the Earth» => 2 , «an apple» => 3 , «a banana» => 4 );
foreach ( $a as $key => $value ) echo » $key : $value \n» ;
>
?>
The above example will output:
an apple: 3 a banana: 4 the Earth: 2 John: 1
See Also
- usort() — Sort an array by values using a user-defined comparison function
- uasort() — Sort an array with a user-defined comparison function and maintain index association
- The comparison of array sorting functions
User Contributed Notes 17 notes
[Editor’s note: the following comment may be factually incorrect]uksort is only usable in the UK
if( $country == «UK» ) <
uksort ();
>else <
echo «You have to live in UK to use uksort().» ;
>
?>
sort with collation, to have umlauts correctly:
uksort($retval, array(Collator::create( ‘de_DE’ ), ‘compare’));
(about sorting an array of objects by their properties in a class — inspired by webmaster at zeroweb dot org at usort function)
I’m using classes as an abstraction for querying records in a database and use arrays of objects to store records that have an 1 to n relationship. E.g. a class «family» has family members stored as an array of objects. Each of those objects prepresents a record in a database related to the family (by it’s familyId).
To identify members, I’m using their memberId as the key of the array e.g. $family->members[$memberId].
To sort the family members AFTER fetching them with the database query, you can use the functions _objSort and sortMembers which will sort the «members» array by key using it’s properties (for space reasons I didn’t include the methods used to open the records):
class familyMember
var $memberId ;
var $familyId ;
var $firstName ;
var $age ;
var $hairColor ;
// .
>
class family
var $familyId ;
var $name ;
var $members = array(); // array of familyMember objects
var $sortFields = array();
var $sortDirections = array();
// .
function _objSort (& $a , & $b , $i = 0 )
$field = $this -> sortFields [ $i ];
$direction = $this -> sortDirections [ $i ];
function sortMembers ( $sortFields )
$i = 0 ;
foreach ( $sortFields as $field => $direction )
$this -> sortFields [ $i ] = $field ;
$direction == «DESC» ? $this -> sortDirections [ $i ] = — 1 : $this -> sortDirections [ $i ] = 1 ;
$i ++;
>
uksort ( $this -> details , array( $this , «_objSort» ));
$this -> sortFields = array();
$this -> sortDirections = array();
>
>
// open a family
$familyId = 5 ;
$family = new family ( $familyId );
$family -> open (); // this will also fetch all members
// sort members by 3 fields
$family -> sortMembers (array( «firstName» => «ASC» , «age» => «DESC» , «hairColor» => «ASC» ));
// output all family members
foreach ( $family -> members as $member )
echo $member -> firstName . » — » . $member -> age . » — » . $member -> hairColor . «
» ;
>
?>
Note that this might not be the fastest thing on earth and it hasn’t been tested very much yet but I hope it’s useful for someone.
Regarding the recursive sorting function above:
Genrally speaking, any recursion can be reimplemented using simple iteration. in the specific case, using recursion to compare strings has a huge performance impact while a simple loop would suffice and be faster and more simple.
Recursion is only good if it simplifies your code or your understanding of the concept. the previous example does neither, especially as it does a lot of repetitive things in each iteration, such as asigning the character order constant, rebuilding it into an array and such
For example, the string comparison could be written as such :
function str_compare($a,$b) $order=»aA??bBcCčČ. «; // longer normally & without that html entities
$default = strlen($a) — strlen($b);
$minlen = strlen($a) < strlen($b) ? strlen($a) : strlen($b);
for ($i = 0; $i < $minlen; $i++) $pos_a=strpos($order,$a[$i]);
$pos_b=strpos($order,$b[$i]);
if ($pos_a != $pos_b)
return $pos_a — $pos_b;
>
return $default;
>
Which is much simpler and faster.
Note that the above function will break for characters that are not listed in $order. it should be failry trivial to fix it.
usort
Сортирует array по значениям, используя предоставленную пользователем функцию сравнения для определения порядка.
Замечание:
Если оба сравниваемых значения эквивалентны, они сохраняют свой первоначальный порядок. До PHP 8.0.0 их относительный порядок в отсортированном массиве не был определён.
Замечание: Эта функция присваивает новые ключи элементам array . Она удалит все существующие ключи, а не просто переупорядочит их.
Список параметров
Функция сравнения должна возвращать целое, которое меньше, равно или больше нуля, если первый аргумент является соответственно меньшим, равным или большим, чем второй.
Возвращение нецелых значений из функции сравнения, таких как число с плавающей точкой ( float ), приведёт к внутреннему приведению возвращаемого значения callback-функции к целому числу ( int ). Таким образом, значения 0.99 и 0.1 будут приведены к целочисленному значению 0 , что позволит сравнить эти значения как равные.
Возвращаемые значения
Функция всегда возвращает true .
Список изменений
Версия | Описание |
---|---|
8.2.0 | Тип возвращаемого значения теперь true ; ранее было bool . |
8.0.0 | Если параметр callback ожидает, что будет передано значение по ссылке, функция теперь выдаст ошибку уровня E_WARNING . |
Примеры
Пример #1 Пример использования usort()
foreach ( $a as $key => $value ) echo » $key : $value \n» ;
>
?>
Результат выполнения данного примера:
Для ещё большего упрощения внутреннего сравнения можно использовать оператор spaceship (космический корабль).
foreach ( $a as $key => $value ) echo » $key : $value \n» ;
>
?>
Замечание:
Очевидно, что для этого тривиального случая более подходит функция sort() .
Пример #2 Пример использования функции usort() с многомерными массивами
function cmp ( $a , $b )
return strcmp ( $a [ «fruit» ], $b [ «fruit» ]);
>
?php
$fruits [ 0 ][ «fruit» ] = «lemons» ;
$fruits [ 1 ][ «fruit» ] = «apples» ;
$fruits [ 2 ][ «fruit» ] = «grapes» ;
foreach ( $fruits as $key => $value ) echo «\$fruits[ $key ]: » . $value [ «fruit» ] . «\n» ;
>
?>
При сортировке многомерного массива переменные $a и $b содержат ссылки на первые два индекса массива.
Результат выполнения данного примера:
$fruits[0]: apples $fruits[1]: grapes $fruits[2]: lemons
Пример #3 Пример использования usort() с методом класса
class TestObj private string $name ;
?php
function __construct ( $name )
$this -> name = $name ;
>
/* This is the static comparing function: */
static function cmp_obj ( $a , $b )
return strtolower ( $a -> name ) strtolower ( $b -> name );
>
>
$a [] = new TestObj ( «c» );
$a [] = new TestObj ( «b» );
$a [] = new TestObj ( «d» );
usort ( $a , [ TestObj ::class, «cmp_obj» ]);
foreach ( $a as $item ) echo $item -> name . «\n» ;
>
?>
Результат выполнения данного примера:
Пример #4 Пример использования функции usort() с применением анонимной функции для сортировки многомерного массива
$array [ 0 ] = array( ‘key_a’ => ‘z’ , ‘key_b’ => ‘c’ );
$array [ 1 ] = array( ‘key_a’ => ‘x’ , ‘key_b’ => ‘b’ );
$array [ 2 ] = array( ‘key_a’ => ‘y’ , ‘key_b’ => ‘a’ );
?php
function build_sorter ( $key ) return function ( $a , $b ) use ( $key ) return strnatcmp ( $a [ $key ], $b [ $key ]);
>;
>
usort ( $array , build_sorter ( ‘key_b’ ));
foreach ( $array as $item ) echo $item [ ‘key_a’ ] . ‘, ‘ . $item [ ‘key_b’ ] . «\n» ;
>
?>
Результат выполнения данного примера:
Пример #5 Пример использования usort() с оператором spaceship (космический корабль)
Оператор spaceship (космический корабль) позволяет прямолинейно сравнивать составные значения по нескольким осям. В следующем примере $people сортируется по фамилии, а затем по имени, если фамилия совпадает.
$people [ 0 ] = [ ‘first’ => ‘Adam’ , ‘last’ => ‘West’ ];
$people [ 1 ] = [ ‘first’ => ‘Alec’ , ‘last’ => ‘Baldwin’ ];
$people [ 2 ] = [ ‘first’ => ‘Adam’ , ‘last’ => ‘Baldwin’ ];
?php
function sorter (array $a , array $b ) return [ $a [ ‘last’ ], $a [ ‘first’ ]] [ $b [ ‘last’ ], $b [ ‘first’ ]];
>
foreach ( $people as $person ) print $person [ ‘last’ ] . ‘, ‘ . $person [ ‘first’ ] . PHP_EOL ;
>
?>
Результат выполнения данного примера:
Baldwin, Adam Baldwin, Alec West, Adam
Смотрите также
- uasort() — Сортирует массив, используя пользовательскую функцию для сравнения элементов с сохранением ключей
- uksort() — Сортирует массив по ключам, используя пользовательскую функцию для сравнения ключей
- Сравнение функций сортировки массивов
User Contributed Notes 10 notes
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.
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
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».
If you need to use usort with a key in the calling method, I wrote this as a utility:
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 ));
>
>
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)
If you want to sort an array according to another array acting as a priority list, you can use this function.
function listcmp ( $a , $b )
<
global $order ;
foreach( $order as $key => $value )
<
if( $a == $value )
<
return 0 ;
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» ;