Главная > Программирование > РНР: настольная книга программиста
<< Предыдущий параграф
Следующий параграф >>
<< Предыдущий параграф Следующий параграф >>
Макеты страниц

20.6. Сортировка массивов в PHP

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

Первая фикция, которую мы рассмотрим, — array_miltisort(). Она позволяет сортировать данные массива в нужном нам направлении. Данная функция возвращает значение булевого типа (true или false). Часто программисту необходимо прямо в самом операторе условия и не только там пользоваться функцией array_multisort, чтобы сократить объем кода, а также время выполнения программы. Синтаксис данной функции:

bool array_multisort(array ar1 [, mixed arg [, mixed... [, array...]]])

Данная функция используется в таких версиях старше Программисты иногда

пытаются использовать в функции array_multisort несколько массивов одновременно, чтобы сортировать несколько матриц сразу или многомерную матрицу, содержащую одну или несколько составляющих. При сортировке поддерживается зависимость индексов массива. Данная ситуация довольно плачевно заканчивается.


ВНИМАНИЕ

В функции array_multisort() нельзя производить сортировку сразу нескольких массивов одновременно.


Сам процесс сортировки заключается непосредственно в составлении таблицы, каждая матрица занимает в ней свое место, затем и происходит эта самая сортировка данных последовательно по строкам таблицы. Данный процесс чем-то похож на функциональные возможности сортировки SQL ORDER BY.

Структура параметров функции array_miltisort() немного необычна, но, с другой стороны, довольно-таки гибка. Самый первый параметр должен являться массивом. Далее, если вы сортируете не один массив, а несколько, предлагается вводить следующие массивы для сортировки, так как данная функция может работать далеко

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

Параметры, устанавливающие порядок сортировки:

SORT_ASC — осуществляет сортировку в порядке возрастания;

SORT_DESC — сортирует в порядке убывания.

Параметры, устанавливающие сортировку по типам:

SORT_REGULAR — осуществляет сортировку как строк, так и чисел;

SORT_NUMERIC — осуществляет сортировку чисел; SORT_STRING — осуществляет сортировку строк.

Чтобы данная спецификация сортировки происходила (была применена к конкретному виду массива), необходимо после каждого массива в функции array_multisort() указывать нужные вам тип и способ сортировки. Если вы это сделаете только для одного массива, на другой она распространяться не будет. Приведем пример работы

с массивами:

<?

$ar1 = array(10, 100, 5, а, 4, 7, 1, 3, 8, b, u, d)

$ar2 = array(1, 3, "2", "1", 10, 20, 10, 40, d, r, f, а, с);

print_r($ar1);

printer($ar2);

array_multisort($ar1, SORT_ASC, SORT_STRING);

array_multisort($ar2, SORT_ASC, SORT_NUMERIC);

print_r($ar1);

print_r($ar2);

?>

Этот пример показывает способ работы с так называемыми параметрами обработки массивов. В первом случае происходит сортировка только строк массива $ar1 в порядке во втором случае — только числовых значений массива $ar2 в порядке возрастания. Результат данной программы:

Array ( [0] => 10 [1] => 100 [2] => 5 [3] => а [4] => 4 [5] => 7 [6] => 1 [7] => 3 [8] => 8 [9] => b [10] => u [11] => d)

Array ([0] => 1 [1] => 3 [2] => 2 [3] => 1 [4] => 10 [5] => 20 [6] => 10 [7] => 40 [8] => d [9] => r [10] => f [11] => а [12] => с)

Array ([0] => 1 [1] => 10 [2] => 100 [3] => 3 [4] => 4 [5] => 5 [6] => 7 [7] => 8 [81 => а [9] => b [10] => d [11] => u)

Array ([0] => с [1] => f [2] => d [3] => r [4] => a [5] => 1 [6] => 1 [7] => 2 [8] => 3 [9] => 10 [10] => 10 [11] => 20 [12] => 40)

Первые два массива — исходные, вторые два — сортированные. Существует также и другие способы сортировки массивов. Например:

<?

$mas = array(100, 10, 100, "v");

$mas2 = array(1, 3, 67, 30);

array_multisort($mas, $mas2);

print_r($mas);

print_r($mas2);

?>

Результатом сортировки при помощи данной функции будут следующие массивы:

Array([0] => v [1] => 10 [2] => 100 [3] => 100)

Array([0] => 30 [1] => 3 [2] => 1 [3] => 67)

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

В следующем примере обратите внимание, каким способом осуществляется работа с массивами:

<?

$ar = array(array (45, 67, "s", 35, "a", "g") , array (1, 4, 8, 7, 1, 3));

array_multisort($ar[0], SORT_ASC, SORT_STRING, $ar[1], SORT_NUMERIC, SORT_DESC);

print_r($ar[0]);

echo "<br>";

print_r($ar[1]);

echo "<br>";

array_multisort($ar[0], SORT_ASC, SORT_STRING, $ar[1], SORT_ASC, SORT_NUMERIC);

print_r($ar[0]);

echo "<br>";

print_r($ar[1]);

echo "<br>";

array_multisort($ar[1], SORT_ASC, SORT_NUMERIC, $ar[0], SORT_ASC, SORT STRING);

print_r($ar[1]);

echo "<br>";

print_r($ar[0]);

echo "<br>";

$ar = array(array (45, 67, "s", 35, "a", "g") , array (1, 4, 8, 7, 1, 3));

array_multisort($ar[0] , SORT_ASC, SORT_STRING); array_multisort ($ar[1],SORT_NUMERIC, S0RT_DESC);

print_r($ar[0]);

echo"<br>";

print_r($ar[1]);

Результаты работы программы:

Array ([0] => 35 [1] => 45 [2] => 67 [3] => a [4] => g [5] => s)

Array ([0] => 7 [1] => 1 [2] => 4 [3] => 1 [4] => 3 [5] => 8)

Array ([0] => 35 [1] => 45 [2] => 67 [3] => a [4] => g [5] => s)

Array ([0] => 7 [1] => 1 [2] => 4 [3] 1 [4] => 3 [5] => 8)

Array ([0] => 1 [1] => 1 => 3 [3] => 4 => 7 [5] => 8)

Array ([0] => 45 [1] => a [2] => g [3] => 67 [4] => 35 [5] => s)

Array ([0] => 35 [1] => 45 [2] => 67 [3] => a [4] => g [5] => s)

Array([0] => 8 [1] => 7 [2] => 4 [3] => 3 => 1 [5] => 1)


ВНИМАНИЕ

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


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

Еще одна функция сортировки значений ассоциативных массивов — arsort() . Легко запоминается и имеет также легко используемый синтаксис:

void arsort(array array [, int sort_flags])

Применяется в PHP 3 и PHP 4. Данная функция применяется в ассоциативных массивах, т. е. она сортирует значения массива в обратном порядке. Эта сортировка применима как к строкам, так и к числам.


ВНИМАНИЕ

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


Приведем пример применения функции arsort():

<?

$world = array("d" => "car", "a"=>"house", "b"=>" apple", "c"=>"table", "e" => "quality");

arsort($world);

reset($world);

while (list ($key, $val) = each ($world)) {

    echo "$key = $val\n";

}

echo "<br>";

$number = array ("d"=>56, "a"=>23, "b"=>89, "c"=>l, "e" => 30 );

arsort($number);

reset($number);

while (list ($key, $val) = each ($number) ) {

    echo "$key = $val\n";

}

?>

Результатом работы этой программы будут следующие строки:

с = table е = quality a = house d = car b = apple

b = 89 d = 56 е = 30 а = 23 с = 1

В первом случае происходит сортировка массива, состоящего из строк, во втором — из численных значений.

Способ сортировки данной функции можно изменять, основные параметры, предназначенные для этого, — такие же, как при использовании функции sort(). Данная функция производит сортировку массива в прямом порядке и имеет следующий синтаксис:

void sort (array array [, int sort_flags].)

Он является аналогичным тому, который имеет функция arsort(). Рассмотрим применяемые в двух данных функциях флаги, т. е. переменные, необходимые для задания способа сортировки:

SORT_REGULAR — сортирует значения массива (как чисел, так и строк);

SORT_NUMERIC — сортирует только числа;

SORT_STRING — сортирует только строки.

Для более полного понимания проделайте следующую операцию. Возьмите функцию arsort() в приведенном выше примере и замените на функцию sort(). Сортировка значений переменных в этом случае будет осуществляться в прямом порядке и результат работы программы будет выглядеть следующим образом:

0 = apple 1 = car 2 = house 3 = quality 4 = table

0 = 1 1 = 23 2 = 30 3 = 56 4 = 89

Применение флагов в данной функции было заложено только с версии РНР 4.


ВНИМАНИЕ

Функция sort() не поддерживает индексную зависимость, т. е. систему указателей в массиве, в отличие от функции сортировки asort().


Функция asort() имеет те же свойства, как и ранее приведенные две функции arsort(), sort(). Приведем синтаксис, хотя он аналогичен предшествующим функциям:

void asort(array array [, int sort_flags])

Если же мы теперь изменим в приведенном ранее примере значения функции arsort() на asort (), то получим:

b = apple d = car a = house e = quality с = table

с = 1 a = 23 e = 30 d = 56 b = 89

Как видно, данная функция позволяет осуществлять сортировку с указателями массива, чего нельзя сделать при использовании функции sort().

Еще одна функция сортировки массивов в обратном порядке — rsort(), она является почти полной аналогией функции sort(), единственное отличие — первая сортирует в обратном порядке, a sort() — в прямом. При подстановке rsort() вместо sort() в вышеописанный пример результат будет следующий:

0 = table 1 = quality 2 = house 3 = car 4 = apple

0 = 89 1 = 56 2 = 30 3 = 23 4 = 1

Функция ksort() сортирует непосредственно по указателю, а не по значению указателей:

а = house b = apple с = table d = car e = quality a = 23 b = 89 с = 1 d = 56 e = 30

Функция krsort() сортирует сами указатели в обратном

е = quality d = car с = table b = apple a = house

e = 30 d = 56 с = 1 b = 89 a = 23

При этом значения нас не интересуют.

Данная функция применяется в РНР старше третьей версии.

Рассмотрим функцию, которая сортирует данные в естественном виде. При обычной сортировке сравнивается каждый последующий символ в алфавитном порядке. Например, нужно отсортировать значения max10, max11, max12, max1, max2, max21, max22. Сортировка, описанная ранее, осуществляется следующим образом: max1, max10, max11, max12, max2, max21, max22. Функция, которая будет рассмотрена, сортирует значения так: max1, max2, max10, max11, max12, max21, max22. Данный способ сортировки и называется натуральной сортировкой, и этим занимается функция natsort(). Функция имеет следующий синтаксис:

void natsort (array array)

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

<?

$arl = $ar2 = array ("max12","maxl0", "max2", "max1"); sort($ar1);

echo "<br>Стандартный порядок сортировки<br>\n"; print_r($ar1);

natsort($array2);

echo "\n<br>Натуральный порядок сортировки<br>\n";

print_r($ar2);

?>

Как видно, в примере приводятся функции sort() и natsort(). Результат работы данной программы приведен ниже:

Стандартный порядок сортировки

Array ([0] => max1 [1] => max10 [2] => max12 [3] => max2)

Натуральный порядок сортировки

Array ([0] => max12 [1] => max10 [2] => max2 [3] => max1)

Если необходимо создать свой сценарий сортировки, чтобы провести сортировку по какому-либо специально установленному условию, то осуществить это в РНР не составит труда. Существуют функции, которые помогают производить переменных, определяемую непосредственно самим программистом. К такому типу относятся следующие функции:

• usort(),

• uksort(),

• uasort().

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

void usort (array array, string any_function)

Принцип ее работы заключается в следующем: она сортирует массив значений, используя определяемую пользователем функцию сравнения. Если массив, который необходимо сортировать, нуждается в использований каких-либо особых условий, вам следует воспользоваться данной функцией. Например:

<?

function des($a, $b) {

    if ($a == $b) return 0;

    return($a < $b);

}

$a = array(3, 2, 2, 5, 6, 1);

usort($a, "des");

while (list ($key, $value) = each ($a)) {

    echo "$key: $value\n";

}

?>

В примере была задана функция, которая будет производить сначала сравнение двух переменных, взятых из массивов $а и $b. После этого, если они равны, функция возвращает значение, равное нулю. Иначе она возвращает значение $а<$Ь. Таким образом и осуществляется сортировка в обратном порядке (имеется в виду по убывающей). Результат работы данной функции:

0: 6

1: 5

2: 3

3: 2

4: 2

5: 1

Обратите внимание, что она работает даже в случае применения повторяющихся значений.

Следующая функция, которую мы рассмотрим, — uksort(). Она осуществляет сортировку не самих значений массива, а именно указателей на них, т. работает с ассоциативными массивами. Сам процесс работы аналогичен приведенной выше функции. Ее синтаксис:

void uksort (array array, function name_function)

Если в рассмотренной выше программе произвести замену массива $а на новый:

$а = array (1 => "один", 2 => "два", 24 => "двадцать четыре", 15 => "пятнадцать");

а функцию usort на uksort то результат программы будет следующий:

24: двадцать четыре

15: пятнадцать

2: два

1: один

Как видно, произошла сортировка не значений указателей, а самих указателей по убыванию. Чтобы сортировка происходила по возрастанию, необходимо вместо знака < поставить знак > в строке return ($а < $b);.

Функция uasort () похожа на ранее описанные функции. Единственное ее отличие заключается в том, что она осуществляет сортировку с поддержкой индексной зависимости массива. Приведем описанный ранее пример с измененными параметрами:

<?

function des($a, $b) {

    if ($а == $b) return 0;

    return ($a < $b);

}

$а = array ( 15, 5, 24, 1);

uasort($a, "des");

while (list ($key, $value) = each ($a)) {

    echo "$key: $value\n";

}

?>

Результат работы данной функции: 2: 24 0: 15 1: 5 3: 1

Обратите внимание на индексную зависимость, о которой было сказано ранее. При пользовании функции uasort() индексная зависимость ни в коем случае не изменяется. Это и делает данную функцию отличной от приведенных выше.

<< Предыдущий параграф Следующий параграф >>
Оглавление