Sorting associative array by value php

uasort

Сортирует array таким образом, чтобы его ключи сохраняли свою корреляцию со значениями, с которыми они связаны, с использованием определяемой пользователем функции сравнения.

Это обычно используется при сортировке ассоциативных массивов, в которых важен актуальный порядок элементов.

Замечание:

Если оба сравниваемых значения эквивалентны, они сохраняют свой первоначальный порядок. До PHP 8.0.0 их относительный порядок в отсортированном массиве не был определён.

Замечание:

Сбрасывает внутренний указатель массива на первый элемент.

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

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

Возвращение нецелых значений из функции сравнения, таких как число с плавающей точкой ( float ), приведёт к внутреннему приведению возвращаемого значения callback-функции к целому числу ( int ). Таким образом, значения 0.99 и 0.1 будут приведены к целочисленному значению 0 , что позволит сравнить эти значения как равные.

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

Функция всегда возвращает true .

Список изменений

Версия Описание
8.2.0 Тип возвращаемого значения теперь true ; ранее было bool .
8.0.0 Если параметр callback ожидает, что будет передано значение по ссылке, функция теперь выдаст ошибку уровня E_WARNING .

Примеры

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

// Функция сравнения
function cmp ( $a , $b ) if ( $a == $b ) return 0 ;
>
return ( $a < $b ) ? - 1 : 1 ;
>

// Сортируемый массив
$array = array( ‘a’ => 4 , ‘b’ => 8 , ‘c’ => — 1 , ‘d’ => — 9 , ‘e’ => 2 , ‘f’ => 5 , ‘g’ => 3 , ‘h’ => — 4 );
print_r ( $array );

// Сортируем и выводим получившийся массив
uasort ( $array , ‘cmp’ );
print_r ( $array );
?>

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

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 )

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

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

User Contributed Notes 20 notes

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

// procedural:
uasort ( $collection , ‘my_sort_function’ );

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

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

Читайте также:  Html css left pad

An Example using anonymous function.
Anonymous functions make some time the code easier to understand.
$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
)

If you want to keep the order when two members compare as equal, use this.

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

User «php at clement dot hk» already provided a stable uasort function, but I find this wrapper much shorter and easier to understand:

function stable_uasort(array &$array, $value_compare_func) $index = 0;
foreach ($array as &$item) $item = array($index++, $item);
>
$result = uasort($array, function($a, $b) use($value_compare_func) $result = call_user_func($value_compare_func, $a[1], $b[1]);
return $result == 0 ? $a[0] — $b[0] : $result;
>);
foreach ($array as &$item) $item = $item[1];
>
return $result;
>

Difference between uasort() and usort(), the missing example .

$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’ ));

Читайте также:  Sending html email in java
[ 2 ] => Array
(
[ id ] => deux
[ aa ] => 22
) [ 10 ] => Array
(
[ id ] => dix
[ aa ] => 1010
) [ 7 ] => Array
(
[ id ] => sept
[ aa ] => 77
)) ?>

*** usort($arr, ‘so’) output:

[ 1 ] => Array
(
[ id ] => deux
[ aa ] => 22
) [ 2 ] => Array
(
[ id ] => dix
[ aa ] => 1010
) [ 3 ] => Array
(
[ id ] => sept
[ aa ] => 77
)) ?>

//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];

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.

/************************************
* 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’ ));

//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 ;
>
>
?>

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:

(assuming, of course, that your sort function is lopping off the $ and evaluating as a number — which would complicate the use of asort() 😉

$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 shuffle assoc array preserving keys just do this:
$array ,
function ( $a , $b ) <
return mt_rand ( 0 , 1 ) > 0 ? 1 : — 1 ;
>
); ?>

Читайте также:  Php current line number

Источник

Sorting Arrays

PHP has several functions that deal with sorting arrays, and this document exists to help sort it all out.

  • Some sort based on the array keys, whereas others by the values: $array[‘key’] = ‘value’;
  • Whether or not the correlation between the keys and values are maintained after the sort, which may mean the keys are reset numerically (0,1,2 . )
  • The order of the sort: alphabetical, ascending (low to high), descending (high to low), natural, random, or user defined
  • Note: All of these sort functions act directly on the array variable itself, as opposed to returning a new sorted array
  • If any of these sort functions evaluates two members as equal then they retain their original order. Prior to PHP 8.0.0, their order were undefined (the sorting was not stable).

Sorting function attributes

Function name Sorts by Maintains key association Order of sort Related functions
array_multisort() value string keys yes, int keys no first array or sort options array_walk()
asort() value yes ascending arsort()
arsort() value yes descending asort()
krsort() key yes descending ksort()
ksort() key yes ascending krsort()
natcasesort() value yes natural, case insensitive natsort()
natsort() value yes natural natcasesort()
rsort() value no descending sort()
shuffle() value no random array_rand()
sort() value no ascending rsort()
uasort() value yes user defined uksort()
uksort() key yes user defined uasort()
usort() value no user defined uasort()

User Contributed Notes 2 notes

While this may seem obvious, user-defined array sorting functions ( uksort(), uasort(), usort() ) will *not* be called if the array does not have *at least two values in it*.

function usortTest ( $a , $b ) var_dump ( $a );
var_dump ( $b );
return — 1 ;
>

$test = array( ‘val1’ );
usort ( $test , «usortTest» );

$test2 = array( ‘val2’ , ‘val3’ );
usort ( $test2 , «usortTest» );

The first array doesn’t get sent to the function.

Please, under no circumstance, place any logic that modifies values, or applies non-sorting business logic in these functions as they will not always be executed.

Another way to do a case case-insensitive sort by key would simply be:

uksort ( $array , ‘strcasecmp’ );
?>

Since strcasecmp is already predefined in php it saves you the trouble to actually write the comparison function yourself.

Источник

Оцените статью