Целта на статията е да се дадат прости и ясни примери за сортиране на масиви по ключове.
Изполва се PHP Version 5.3.8;

Съдържание

 

  1. Кратък преглед на функциите за сортиране.
  2. Примери
  3. Заключение

 

Кратък преглед на функциите за сортиране.

В PHP има няколко функции за сортиране на масиви по ключ. Това са:

  1. krsort()
  2. ksort()
  3. uksort()

и т.н.

Пълният списък на сортиращите функции може да се види на:
http://php.net/manual/en/array.sorting.php

Ще се спрем на третата функция – uksort(). Тя позволява да се сортира по ключовете на масив като се използва потребителска функция за сравнение на стойностите на ключовете.



Предстоящо събитие на потребителска група .NET

Secure your ASP.NET API using OAuth 2.0

Дата: 28 Февруари


 


Каква е тази потребителска функция за сравнение? Ако искаме да подредим дадено множество от елементи, трябва да имаме критерий за сравнение. Например човек, който оценява песни. Човекът представлява функцията. Той може да направи класация в зависимост от своите музикални критерии – операторите във функцията. Така и функцията за сортиране може да прецени сред дадени елементи дали два от тях са равни или ако не кой от тях е „по-голям“.

Функцията uksort приема два параметъра (и връща TRUE при успех или FALSE при неуспех или NULL): първи масива, който ще се сортира и втори стринг с името на функцията. Вторият параметър може да бъде и анонимна функция, но тука няма да използваме този начин.

Функцията за сортиране също има определена сигнатура. Тя приема два аргумента $a, $b, които представляват променливи от тип еднакъв с типа на ключовете на масива, който се сортира. Функцията трябва да върне отрицателна стойност ако $a < $b положителна стойност, ако $a > $b и 0, ако $a == $b. По този начин uksort може да извърши сортиране.

Описанието може да се прочете тук:
http://php.net/manual/en/function.uksort.php

Преди да преминем към примерите да си подготвим тестовите данни. Това са два масива – $numbers с числа за ключове и $names със имена на хора за ключове и съответните им адреси за стойности.

  1. $numbers = array(1, 2, 3, 4, 5, 6, 7, 8, 9);
  2. $names[„Александрър Александров“] = „адрес 1“;
  3. $names[„Боян Филипов“] = „адрес 2“;
  4. $names[„Цветомор Ясенов“] = „адрес 3“;
  5. $names[„Драган Василев“] = „адрес 4“;
  6. $names[„Петър Васев“] = „адрес 5“;
  7. $names[„Мария Петрова“] = „адрес 6“;
  8. $names[„Ангелина Ангелова“] = „адрес 7“;

 

Примери.

1. Сортираща функция с празно тяло.

  1. // функция с празно тяло
  2. function comp1($a, $b) {
  3. }
  4. $t = uksort($numbers, „comp1“);
  5. print ‘<pre>’;
  6. print_r($numbers);

Като резултат получаваме:

  1. Array
  2. (
  3.        [6] => 7
  4.        [7] => 8
  5.        [8] => 9
  6.        [5] => 6
  7.        [4] => 5
  8.        [1] => 2
  9.        [2] => 3
  10.       [3] => 4
  11.       [0] => 1
  12. )

Виждаме, че ключовете са разбъркани.

2. Естествена подредба.
А каква би била функцията, ако искаме индексите да са подредени по големина, както е по подразбиране при масивите?
Ето така:

  1. function comp2($a, $b) {
  2.             if ($a < $b) {
  3.             return 1;
  4.             } else if ($a === $b) {
  5.             return 0;
  6.             } else {
  7.             return 1;
  8.             }
  9. }
  10. // или по-кратко:
  11. function comp2_1($a, $b) {
  12.             return $a $b;
  13. }
  14. $t = uksort($numbers, „comp2“);
  15. print ‘<pre>’;
  16. print_r($numbers);

Вече имаме:

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

3. Обърната подредба.
А ако искаме индексите да са в намаляващ ред?

  1. function comp3($a, $b) {
  2.             if ($a < $b) {
  3.                       return 1;
  4.             } else if ($a === $b) {
  5.                       return 0;
  6.             } else {
  7.                       return 1;
  8.             }
  9. }
  10. //Или по-кратко:
  11. function comp3_1($a, $b) {
  12.             return $b $a;
  13. }
  14. $t = uksort($numbers, „comp3“);
  15. print ‘<pre>’;
  16. print_r($numbers);

И резултатът е:

  1. Array
  2. (
  3.        [8] => 9
  4.        [7] => 8
  5.        [6] => 7
  6.        [5] => 6
  7.        [4] => 5
  8.        [3] => 4
  9.        [2] => 3
  10.       [1] => 2
  11.       [0] => 1
  12. )

4. Първо четните индекси.
Малко по-сложна задача. Искаме първо да са четните индекси в намаляващ ред и след тях нечетните в намаляващ ред.

  1. function comp4($a, $b) {
  2.             // ако $a е четно а $b не е, то $a е „по-малко“ от $b
  3.             if ($a % 2 == 0 && $b % 2 != 0) {
  4.                        return 1;
  5.             } // ако $a е четно и $b е четно, то $a е „равно“ на $b
  6.             else if ($a % 2 == 0 && $b % 2 == 0) {
  7.                        // но искаме самите четни индекси да са подредени
  8.                        // подреждаме четните индекси
  9.                        if ($a < $b) {
  10.                                  return 1;
  11.                        } else if ($a > $b) {
  12.                                  return 1;
  13.                        } else {
  14.                                  return 0;
  15.                        }
  16.             } // ако $a и $b са нечетни
  17.             else if ($a % 2 != 0 && $b % 2 != 0) {
  18.                        // подреждаме нечетните индески
  19.                        if ($a < $b) {
  20.                                  return 1;
  21.                        } else if ($a > $b) {
  22.                                  return 1;
  23.                        } else {
  24.                                  return 0;
  25.                        }
  26.             } // ако $a четно, а $b е нечетно
  27.             else {
  28.                       return 1;
  29.             }
  30. }
  31. $t = uksort($numbers, „comp4“);
  32. print ‘<pre>’;
  33. print_r($numbers);

Резултат:

  1. Array
  2. (
  3.        [0] => 1
  4.        [2] => 3
  5.        [4] => 5
  6.        [6] => 7
  7.        [8] => 9
  8.        [1] => 2
  9.        [3] => 4
  10.        [5] => 6
  11.        [7] => 8
  12. )

4. Подреждане по фамилия.
Задачата изглежда сложна, но всъщност не е.

  1. function comp5($a, $b) {
  2.             $a_arr = explode(“ „, $a);
  3.             $b_arr = explode(“ „, $b);
  4.             return strcoll($a_arr[1], $b_arr[1]);
  5. }
  6. $t = uksort($names, „comp5“);
  7. print ‘<pre>’;
  8. print_r($names);

Получаваме:

  1. Array
  2. (
  3.        [Александрър Александров] => адрес 1
  4.        [Ангелина Ангелова] => адрес 7
  5.        [Петър Васев] => адрес 5
  6.        [Драган Василев] => адрес 4
  7.        [Мария Петрова] => адрес 6
  8.        [Боян Филипов] => адрес 2
  9.        [Цветомор Ясенов] => адрес 3
  10. )

 

Заключение

Сортиращите функции не са характерни само за PHP. Ето някои примери и за други езици:

Javascript – http://www.w3schools.com/jsref/jsref_sort.asp
Perl – http://perldoc.perl.org/functions/sort.html
Java – http://www.avajava.com/tutorials/lessons/how-do-i-sort-an-array-of-objects-with-a-comparator.html

Така че познанията тук (PHP) може да са полезни и в други езици.

Приятно кодиране 🙂

Автор: Янко Попов