Php array sort key string

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

В продолжении темы работы с массивами поговорим о типичной задаче – их сортировке. Для ее выполнения в PHP существует множество функций, их подробное описание можно посмотреть на php.net, рассмотрим некоторые примеры.

Сортировка массива по ключу

ksort() и krsort() – сортирует массив по ключу.

$array = array( 3 => 'яблоко', 1 => 'апельсин', 5 => 'виноград' ); // По возрастанию: ksort($array); print_r($array); // По убыванию: krsort($array); print_r($array);

Результат:

Array ( [1] => апельсин [3] => яблоко [5] => виноград ) Array ( [5] => виноград [3] => яблоко [1] => апельсин )

Сортировка массива по значению

Функции sort() и rsort() сортирует массив по значению, при этом не сохраняя ключи.

$array = array( 3 => 'яблоко', 1 => 'апельсин', 5 => 'виноград' ); // По возрастанию: sort($array); print_r($array); // По убыванию: rsort($array); print_r($array);

Результат:

Array ( [0] => апельсин [1] => виноград [2] => яблоко ) Array ( [0] => яблоко [1] => виноград [2] => апельсин )

Чтобы сохранить ключи применяется функции asort() и arsort() .

$array = array( 3 => 'яблоко', 1 => 'апельсин', 5 => 'виноград' ); // По возрастанию: asort($array); print_r($array); // По убыванию: arsort($array); print_r($array);

Результат:

Array ( [1] => апельсин [5] => виноград [3] => яблоко ) Array ( [3] => яблоко [5] => виноград [1] => апельсин )

Естественная сортировка

Выше приведенные функции по умолчанию используют алгоритм Quicksort (быстрая сортировка). Чтобы изменить алгоритм нужно вторым аргументом указать флаг:

SORT_REGULAR Обычное сравнение элементов (без изменения типов)
SORT_NUMERIC Числовое сравнение элементов
SORT_STRING Строковое сравнение элементов
SORT_LOCALE_STRING Сравнивает элементы как строки с учетом текущей локали.
SORT_NATURAL Также как natsort()
SORT_FLAG_CASE Может быть объединен с SORT_STRING или SORT_NATURAL для сортировки строк без учета регистра.

Привычную для человека сортировку делают функции natsort() , natcasesort() или флаг SORT_NATURAL .
natcasesort() сортирует массив без учета регистра символов.

Разницу можно увидеть в примере:

$array = array(-1, 0, 10, 'текст', 'a', 'b'); // Quicksort: sort($array); print_r($array); // Natural order: natsort($array); print_r($array);

Результат:

Array ( [0] => -1 [1] => a [2] => b [3] => 0 [4] => текст [5] => 10 ) Array ( [0] => -1 [1] => 0 [2] => 10 [4] => a [5] => b [3] => текст )

У natsort() нет возможности изменить направление сортировки, поэтому можно применить функцию array_reverse() .

natsort($array); $array = array_reverse($array); print_r($array);

Результат:

Array ( [0] => текст [1] => b [2] => a [3] => 10 [4] => 0 [5] => -1 )

Сортировка многомерных массивов

array_multisort() сортирует многомерные массивы по значению, также может отсортировать сразу несколько массивов.

$array = array( array(20, 222, 2, 22), array(10, 111, 1, 11), ); array_multisort($array); print_r($array);

Результат:

Array ( [0] => Array( [0] => 10 [1] => 111 [2] => 1 [3] => 11 ) [1] => Array( [0] => 20 [1] => 222 [2] => 2 [3] => 22 ) )

Чтобы изменить направление сортировки вторым аргументом функции указывается SORT_ASC или SORT_DESC .

array_multisort($array, SORT_DESC); print_r($array);

Сортировка многомерного массива по значению одного ключа

Есть несколько вариантов, первый – uasort() , сортирует массив, используя пользовательскую функцию для сравнения элементов и сохранением ключей.

Читайте также:  Writing json file in python

В примере сортировка идет по ключу « count ».

$array = array( array( 'sku' => '645908-463', 'count' => '1' ), array( 'sku' => '64590644', 'count' => '20' ), array( 'sku' => '7543', 'count' => '2' ) ); // По возрастанию: function cmp_function($a, $b) < return ($a['count'] >$b['count']); > uasort($array, 'cmp_function'); print_r($array); // По убыванию: function cmp_function_desc($a, $b) < return ($a['count'] < $b['count']); >uasort($array, 'cmp_function_desc'); print_r($array);

Результат:

Array ( [0] => Array( [sku] => 645908-463 [count] => 1 ) [2] => Array( [sku] => 7543 [count] => 2 ) [1] => Array( [sku] => 64590644 [count] => 20 ) ) Array ( [1] => Array( [sku] => 64590644 [count] => 20 ) [2] => Array( [sku] => 7543 [count] => 2 ) [0] => Array( [sku] => 645908-463 [count] => 1 ) )

Второй вариант на основе функции array_multisort() :

function array_multisort_value() < $args = func_get_args(); $data = array_shift($args); foreach ($args as $n =>$field) < if (is_string($field)) < $tmp = array(); foreach ($data as $key =>$row) < $tmp[$key] = $row[$field]; >$args[$n] = $tmp; > > $args[] = &$data; call_user_func_array('array_multisort', $args); return array_pop($args); > $array = array( array( 'sku' => '645908-463', 'count' => '1' ), array( 'sku' => '64590644', 'count' => '20' ), array( 'sku' => '7543', 'count' => '2' ) ); $array = array_multisort_value($array, 'count', SORT_DESC); print_r($array);

Перемешать массив

Функция shuffle() перемешивает массив в случайном порядке, не сохроняя ключи.

$array = array( 1 => 'яблоко', 2 => 'апельсин', 3 => 'виноград' ); shuffle($array); print_r($array); shuffle($array); print_r($array);

Результат:

Array ( [0] => виноград [1] => яблоко [2] => апельсин ) Array ( [0] => виноград [1] => апельсин [2] => яблоко ) 

Источник

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

В PHP есть несколько функций для сортировки массивов, на этой странице даётся их общее описание.

Основные различия между функциями:

  • В одних функциях массивы ( array ) сортируются по ключам элементов, в других по значениям: $array[‘ключ’] = ‘значение’;
  • В каких-то функциях связь между ключами и значениями после сортировки сохраняется, в каких-то нет. Это может приводить к тому, что ключи будут сбрасываться в числовые значения (0, 1, 2, . ).
  • Различия в порядке сортировки: алфавитный, возрастающий, убывающий, числовой, естественный, случайный или определённый пользователем
  • Примечание: Все функции сортировки модифицируют переданный массив, а не возвращают отсортированную копию
  • Если какая-либо из этих функций сортировки оценивает два элемента как равные, они сохраняют свой исходный порядок. До PHP 8.0.0 их порядок не был определён (сортировка была нестабильной).

Свойства функций сортировки

Имя функции Сортирует по Сохраняет связь ключ — значение Порядок сортировки Похожие функции
array_multisort() значению строковые ( string ) ключи да, числовые ( int ) — нет первый массив или настройки сортировки array_walk()
asort() значению да по возрастанию arsort()
arsort() значению да по убыванию asort()
krsort() ключу да по убыванию ksort()
ksort() ключу да по возрастанию krsort()
natcasesort() значению да естественный, нечувствительный к регистру natsort()
natsort() значению да естественный natcasesort()
rsort() значению нет по убыванию sort()
shuffle() значению нет случайный array_rand()
sort() значению нет по возрастанию rsort()
uasort() значению да определяется пользователем uksort()
uksort() ключу да определяется пользователем uasort()
usort() значению нет определяется пользователем uasort()
Читайте также:  Php форма обратной связи через smtp

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.

Источник

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

$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).

Читайте также:  Система координат в css

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.

Источник

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