На странице произошла ошибка #S51. Свяжитесь с вебмастером. PHP 5.6 и PHP 7 на русском: Функция uksort() - Сортирует массив по ключам, используя пользовательскую функцию для сравнения ключей

uksort

(PHP 4, PHP 5)

uksortСортирует массив по ключам, используя пользовательскую функцию для сравнения ключей

Описание

bool uksort ( array &$array , callable $cmp_function )

uksort() отсортирует массив, используя для сравнения его ключей функцию, предоставленную пользователем. Используйте эту функцию, если массив должен быть отсортирован по какому-нибудь необычному признаку.

Список параметров

array

Входной массив.

cmp_function

Функция сравнения должна возвращать целое, которое меньше, равно или больше нуля, если первый аргумент является соответственно меньшим, равным или большим чем второй.

int callback ( mixed $a, mixed $b )

Возвращаемые значения

Возвращает TRUE в случае успешного завершения или FALSE в случае возникновения ошибки.

Примеры

Пример #1 Пример использования uksort()

<?php
function cmp($a$b)
{
    
$a preg_replace('@^(a|an|the) @'''$a);
    
$b preg_replace('@^(a|an|the) @'''$b);
    return 
strcasecmp($a$b);
}

$a = array("John" => 1"the Earth" => 2"an apple" => 3"a banana" => 4);

uksort($a"cmp");

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

Результат выполнения данного примера:

an apple: 3
a banana: 4
the Earth: 2
John: 1

Смотрите также

Коментарии

To use a more complicated comparison function, one can use a callback to a method of an object instance.
For example the following will take an array $arr whose keys are the same as those of $reference, and reorder $arr so that the keys appear in the same order as in $reference.

class kcmp {
    var $reference ;
    function kcmp( $reference ) {
       $this->reference = $reference ; 
    }
    function kcompare( $a, $b ) {
       $keys = array_keys( $this->reference ) ;
       $position_a = array_search( $a, $keys ) ;
       $position_b = array_search( $b, $keys ) ;
       return  $position_a < $position_b ? -1 : 1 ;   
    }
}

$reference = array(
    "k2" => "a2",
    "k3" => "a3",
    "k1" => "a1"
) ;
$arr = array(
    "k1" => "b1",
    "k2" => "b2",
    "k3" => "b3"
) ;
print_r( $arr ) ; 
uksort( $arr, array( new kcmp( $reference ), "kcompare" ) ) ;
print_r( $arr ) ;
2003-11-13 12:59:13
http://php5.kiev.ua/manual/ru/function.uksort.html
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&#269;&#268;..."; // 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.
2003-12-07 14:18:26
http://php5.kiev.ua/manual/ru/function.uksort.html
The code below allows you to sort an array_A following array_B keys order, original keys and values remain associated.

<?

//main function
Function SortArrayAKeysLikeArrayBKeys(&$TheArrayToSort){
   
uksort($TheArrayToSort,"SortArrayAKeysLikeArrayBKeys_cmp");
}

//the custom compare function
Function SortArrayAKeysLikeArrayBKeys_cmp($a,$b){
  global 
$TheArrayOrder;
 
$PosA=KeyPosInArray($a,$TheArrayOrder);
 
$PosB=KeyPosInArray($b,$TheArrayOrder);
  if (
$PosA==$PosB){return 0;}else{return ($PosA $PosB : -1);}
}

//where is my key in my array
Function KeyPosInArray($Key,$Array){
   
$i=0;
   
$Pos=99999999;
   if(
$Array){
      foreach(
$Array as $K => $V){
         
$i++;
         if(
$K==$Key){
           
$Pos=$i;
            break;
         }
      }
   }
   return 
$Pos;
}

//the array you want to sort
$AnyArrayToSort['age']='19';
$AnyArrayToSort['ville']='rennes';
$AnyArrayToSort['website']='kik-it.com';
$AnyArrayToSort['region']='bretagne';
$AnyArrayToSort['code_postal']='35200';
$AnyArrayToSort['Nom']='Fred';

//the array with the correct keys/values order
$TheArrayOrder['Nom']='Whatever';
$TheArrayOrder['age']='Anything';
$TheArrayOrder['region']='What u want';
$TheArrayOrder['ville']='Something';
$TheArrayOrder['code_postal']='Nothing';

//before sort
print_r($AnyArrayToSort);   
echo 
"<br>";
//we sort
SortArrayAKeysLikeArrayBKeys($AnyArrayToSort);
echo 
"<br>";
//after sort
print_r($AnyArrayToSort);
?>

Will print :

Array ( [age] => 19 [ville] => rennes [website] => kik-it.com [region] => bretagne [code_postal] => 35200 [Nom] => Fred ) 

Array ( [Nom] => Fred [age] => 19 [region] => bretagne [ville] => rennes [code_postal] => 35200 [website] => kik-it.com ) 

The keys not listed in the $TheArrayOrder will appear at the end of your sorted array (only if Key Pos < 99999999 ;o)
2004-02-09 12:03:25
http://php5.kiev.ua/manual/ru/function.uksort.html
(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):
<?php
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];
       
       
$diff strnatcmp($this->details[$a]->$field$this->details[$b]->$field) * $direction;
        if (
$diff == && isset($this->sortFields[++$i]))
        {
           
$diff $this->_objSort($a$b$i);
        }
       
        return 
$diff;
    }
   
    function 
sortMembers($sortFields)
    {
       
$i 0;
        foreach (
$sortFields as $field => $direction)
        {
           
$this->sortFields[$i] = $field;
           
$direction == "DESC" $this->sortDirections[$i] = -$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."<br />";
}
?>

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.
2004-07-08 09:26:23
http://php5.kiev.ua/manual/ru/function.uksort.html
Here is a small and very fast object to handle sorting of multidimentional arrays by a key.
<?php
/**
* Handles multidimentional array sorting by a key (not recursive)
*
* @author Oliwier Ptak <aleczapka at gmx dot net>
*/
class array_sorter
{
    var 
$skey false;
    var 
$sarray false;
    var 
$sasc true;

   
/**
    * Constructor
    *
    * @access public
    * @param mixed $array array to sort
    * @param string $key array key to sort by
    * @param boolean $asc sort order (ascending or descending)
    */
   
function array_sorter(&$array$key$asc=true)
    {
       
$this->sarray $array;
       
$this->skey $key;
       
$this->sasc $asc;
    }

   
/**
    * Sort method
    *
    * @access public
    * @param boolean $remap if true reindex the array to rewrite indexes
    */
   
function sortit($remap=true)
    {
       
$array = &$this->sarray;
       
uksort($array, array($this"_as_cmp"));
        if (
$remap)
        {
           
$tmp = array();
            while (list(
$id$data) = each($array))
               
$tmp[] = $data;
            return 
$tmp;
        }
        return 
$array;
    }

   
/**
    * Custom sort function
    *
    * @access private
    * @param mixed $a an array entry
    * @param mixed $b an array entry
    */
   
function _as_cmp($a$b)
    {
       
//since uksort will pass here only indexes get real values from our array
       
if (!is_array($a) && !is_array($b))
        {
           
$a $this->sarray[$a][$this->skey];
           
$b $this->sarray[$b][$this->skey];
        }

       
//if string - use string comparision
       
if (!ctype_digit($a) && !ctype_digit($b))
        {
            if (
$this->sasc)
                return 
strcasecmp($a$b);
            else 
                return 
strcasecmp($b$a);
        }
        else
        {
            if (
intval($a) == intval($b)) 
                return 
0;

            if (
$this->sasc)
                return (
intval($a) > intval($b)) ? -1;
            else
                return (
intval($a) > intval($b)) ? : -1;
        }
    }

}
//end of class
?>

Sample $input_array:

Array
(
    [0] => Array
        (
            [id] => 961
            [uid] => 29
            [gid] => 12
            [parent_id] => 147
            [created] => 20041206105350
            [modified] => 20041206110702
        )

    [1] => Array
        (
            [id] => 41
            [uid] => 29
            [gid] => 12
            [parent_id] => 153
            [created] => 20041025154009
            [modified] => 20041206105532
        )

    [2] => Array
        (
            [id] => 703
            [uid] => 29
            [gid] => 12
            [parent_id] => 419
            [created] => 20041025154132
            [modified] => 20041027150259
        )

Example of usage:
<?php
   
function multi_sort(&$array$key$asc=true)
    {
       
$sorter = new array_sorter($array$key$asc);
        return 
$sorter->sortit();
    }
   
//sort by parent_id in descending order
   
$my_array multi_sort($input_array"parent_id"false);
?>

The result array will be:
Array
(

    [0] => Array
        (
            [id] => 703
            [uid] => 29
            [gid] => 12
            [parent_id] => 419
            [created] => 20041025154132
            [modified] => 20041027150259
        )

    [1] => Array
        (
            [id] => 41
            [uid] => 29
            [gid] => 12
            [parent_id] => 153
            [created] => 20041025154009
            [modified] => 20041206105532
        )

    [2] => Array
        (
            [id] => 961
            [uid] => 29
            [gid] => 12
            [parent_id] => 147
            [created] => 20041206105350
            [modified] => 20041206110702
        )
2004-12-06 06:27:45
http://php5.kiev.ua/manual/ru/function.uksort.html
To sort dates with uksort:

function datediff($a, $b) {
   

$a = date('U',$a);
$b = date('U',$b);

if ($a == $b) $r = 0;
else $r = ($a > $b) ? 1: -1;

return $r;
}
2004-12-17 09:41:47
http://php5.kiev.ua/manual/ru/function.uksort.html
One remark regarding array_sorter class.
It won't work correctly with eg. dates from mysql like 20041206105350, cause you can't convert such number into integer. To fix it remove intval() from the code. If the variable is a number it will work without converting this to int anyways. Here is the fix.

<?php
....
if (
$a == $b
    return 
0;
if (
$this->sasc)
    return (
$a $b) ? : -1;
else
    return (
$a $b) ? -1;
...
?>
2004-12-22 06:35:31
http://php5.kiev.ua/manual/ru/function.uksort.html
Автор:
...

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

function uksort_tree ( &$array )
{
    // [PHP5] foreach ( $array as &$value )
    foreach ( $array as $key => $value )
    {
       if ( is_array ( $value ) )
       {
            // [PHP5] uksort_tree ( $value );
           uksort_tree ( $array[$key] );
       }
    }

    uksort( $array, "cmp" );
}

uksort_tree( $myEntryArray );

...
2005-03-19 21:30:37
http://php5.kiev.ua/manual/ru/function.uksort.html
If you need to periodically sort by grades (A, A+, D-, etc.), here is a compare function that compares strings by the case-insensitive method, unless it finds a grade, in which case it correctly sorts by putting "plus" grades first, unmarked grades second, and "minus" grades last.

<?php
function cmp($a$b)
{
   
$a preg_replace('@^(a|an|the) @'''$a);
   
$b preg_replace('@^(a|an|the) @'''$b);

   
//special code for grades
   
if (strpos$a"+") !== false || strpos$b"+") !== false  || 
       
strpos$a"-") !== false || strpos$b"-") !== false ){

       
$substrA substr($a01);
       
$substrB substr($b01);       

       
$modifierA = (strlen($a) == 2) ? substr($a11) : "";
       
$modifierB = (strlen($b) == 2) ? substr($b11) : "";
   
        if (
$substrA == $substrB){
           
//figure out plusses and minuses.
           
if ($modifierA == "+"){
                return -
1;
            } else if (
$modifierB == "+"){
                return 
1;
            }
       
            if (
$modifierA == "-"){
                return 
1;
            } else if (
$modifierB == '-'){
                return -
1;
            }
        } else {
            return 
strcasecmp($a$b);
        }
 
    }
   return 
strcasecmp($a$b);
}

$grades = array( 
                 
"C+" => 13    ,
               
"C" => 10     ,
               
"D+" => 8     ,
               
"B+" => 7     ,
               
"C-" => 6     ,
               
"A-" => 5     ,
               
"F" => 5      ,
               
"B" => 4      ,
               
"B-" => 4     ,
               
"D" => 3      ,
               
"D-" => 3     ,
               
"A+" => 1
   
); 

uksort($grades"cmp");
?>

result:  Array
(
    [A+] => 1
    [A-] => 5
    [B+] => 7
    [B] => 4
    [B-] => 4
    [C+] => 13
    [C] => 10
    [C-] => 6
    [D+] => 8
    [D] => 3
    [D-] => 3
    [F] => 5
)
2009-07-07 10:58:15
http://php5.kiev.ua/manual/ru/function.uksort.html
need a case insensitive sort by key function? i did and couldn find it, so:

<?php
function insensitive_uksort($a,$b) {
    return 
strtolower($a)<strtolower($b);
}
uksort($arr"insensitive_uksort");
?>
2009-07-29 09:56:29
http://php5.kiev.ua/manual/ru/function.uksort.html
Case insensitive without own function:

uksort($array, "strnatcasecmp");
2010-05-23 14:26:49
http://php5.kiev.ua/manual/ru/function.uksort.html
sort with collation, to have umlauts correctly:

uksort($retval, array(Collator::create( 'de_DE' ), 'compare'));
2014-05-05 16:30:40
http://php5.kiev.ua/manual/ru/function.uksort.html
Автор:
[Editor's note: the following comment may be factually incorrect]

uksort is only usable in the UK
<?php
if($country=="UK"){
 
uksort();
}else{
  echo 
"You have to live in UK to use uksort().";
}
?>
2015-02-06 19:32:19
http://php5.kiev.ua/manual/ru/function.uksort.html
Автор:
An associative array with known keys can be easily custom sorted using a switch statement in the callback:

NB ksort can be used beforehand to ensure expected results

ksort($array);

uksort($array, function ($a) {                   
    switch($a) {
        case 'pepperoni':
            return 0;
        case 'beef':
            return 1;
        case 'chicken':
            return 2;
        case 'ham':
            return 3;
        case 'vegetarian':
            return 4;
    }
});
2015-10-05 16:02:11
http://php5.kiev.ua/manual/ru/function.uksort.html
I needed to be able to sort a string that contained numbers eg.

"Slot 1 name"
"Slot 2 name"
"Slot 10 name"

using a normal string compare the "Slot 10 name" would appear before "Slot 2 name" so I wrote little function that will compare a string taking numbers in to consideration. There may be a few edge cases that need to be taken in to consideration.

function strCmpWithNumbers( $a, $b) {
  // Split the string in to words.
  $a = explode(' ',$a);
  $b = explode(' ',$b);
  $loop = 0;
  do {
    // Get the first word from each item
    $ta = Utils::gvfa($a, $loop);
    $tb = Utils::gvfa($b, $loop);
   
    if (isset($ta)) {
      if (isset($tb)) {
        if (is_numeric($ta)) {
          if ($ta != $tb) {
            return $ta - $tb;
          }
        } else {
          $val = strcasecmp($ta, $tb);
          if ($val != 0) {
            return $val;
          }
        }
      } else {
        return 1; // a is set but b isn't
      }
    } else {
      return isset($b);
    }
    $loop +=1;
  } while (true);
}
2016-02-24 12:58:09
http://php5.kiev.ua/manual/ru/function.uksort.html
Автор:
Don't use uksort($array, "strnatcasecmp"); ... use ksort($array, SORT_NATURAL|SORT_FLAG_CASE);
2018-06-22 21:48:43
http://php5.kiev.ua/manual/ru/function.uksort.html
This might be obvious to many, but just to help others that are trying to use this in a class.  Inside a class, you can prefix the function with self:: within the uksort(), and it will work.  Also, if it is in another class that is included, you can prefix it with the class name.

class someclass {
     private function ArraySortCMPIP($a, $b) {
          $a = ip2long($a);
          $b = ip2long($b);

          if ($a == $b) return 0;
          return ($a < $b) ? -1 : 1;
     }

     // Output
     public function PrintResults() {
          uksort($this->someIPAddressArray, 'self::ArraySortCMPIP');
          print_r($this->someIPAddressArray);
     }
}
2021-01-29 21:17:34
http://php5.kiev.ua/manual/ru/function.uksort.html

    Поддержать сайт на родительском проекте КГБ