ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 24.05.2024

Просмотров: 35

Скачиваний: 0

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

4 Сортування масивів

Необхідність сортування даних, у тому числі й даних, що зберігаються у вигляді масивів, дуже часто виникає при рішенні найрізноманітніших завдань. Якщо в мові С для того, щоб вирішити це завдання, потрібно написати десятки рядків коду, то в PHP це робиться однією простою командою.

Функція sort

Функція sort має наступний синтаксис

sort (масив [, прапори])

і сортує масив, тобто впорядковує його значення по зростанню. Ця функція видаляє всі існуючі в масиві ключі, заміняючи їхніми числовими індексами, що відповідають новому порядку елементів. У випадку успішного завершення роботи вона повертає true, інакше - false.

Приклад 7.6.Нехай у нас є два масиви: ціни товарів - їхньої назви й, навпаки, назви товарів - їхньої ціни. Упорядкуємо ці масиви по зростанню:

<?

$items = array(10 => "хліб", 20 => "молоко", 30 => "бутерброд");

sort($items);

// рядки сортуються в алфавітному порядку, ключі губляться

print_r($items);

$rev_items = array("хліб" => 10, "бутерброд" => 30, "молоко" => 20);

sort($rev_items);

// числа сортуються по зростанню, ключі губляться

print_r($rev_items);

?>

Приклад 7.6. Застосування функції sort()

Одержимо:

Array ( [0] => бутерброд [1] => молоко [2] => хліб )

Array ( [0] => 10 [1] => 20 [2] => 30)

Як додатковий аргумент може використатися одна з наступних констант:

SORT_REGULAR - порівнювати елементи масиву звичайним образом;

SORT_NUMERIC - порівнювати елементи масиву як числа;

SORT_STRING - порівнювати елементи масиву як рядка.

Функції asort, rsort, arsort

Якщо потрібно зберігати індекси елементів масиву після сортування, то потрібно використати функцію asort (масив [, прапори]) . Якщо необхідно відсортувати масив у зворотному порядку, тобто від найбільшого значення до найменшого, то можна задіяти функцію rsort (масив [, прапори]) . А якщо при цьому потрібно ще й зберегти значення ключів, то варто використати функцію arsort(масив [, прапори]) . Як ви, напевно, помітили синтаксис у цих функцій абсолютно такий же, як у функції sort . Відповідно й значення прапорів можуть бути такими ж, як в sort : SORT_REGULAR , SORT_NUMERIC , SORT_STRING . До речі кажучи, прапор SORT_NUMERIC з'явився тільки в PHP4.

<?php

$books = array("Пушкін"=>"Руслан і Людмила", "Толстой"=>"Війна й мир", "Лермонтов"=>"Герой нашого часу");


asort($books);

// сортуємо масив, зберігаючи значення ключів

print_r($books);

echo "<br>";

rsort($books);

// сортуємо масив у зворотному порядку, ключі будуть замінені

print_r($books);

?>

Приклад 7.7. Застосування функцій asort, rsort, arsort

У результаті роботи цього скрипта одержимо:

Array ( [Толстой] => Війна й мир

[Лермонтов] => Герой нашого часу

[Пушкін] => Руслан і Людмила )

Array ( [0] => Руслан і Людмила

[1] => Герой нашого часу

[2] => Війна й мир )

Приклад 7.8. Допустимо, ми створюємо каталог описів документів. У кожного документа є автор, назва, дата публікації й короткий зміст. Ми вже не раз відображали описи, складені із цих характеристик. Щораз порядок відображення цих елементів залежав від створеної нами програми. Тепер же ми хочемо мати можливість змінювати порядок відображення елементів за бажанням користувача. Складемо для цього наступну форму:

<form action=task.php>

<table border=1>

<tr><td>Назва </td><td><input type=text name=title size=5> </td></tr>

<tr><td>Короткий зміст </td><td><input type=text name=description size=5> </td></tr>

<tr><td>Автор </td><td><input type=text name=author size=5> </td></tr>

<tr><td>Дата публікації </td><td><input type=text name=published size=5> </td></tr>

</table>

<input type=submit value="Відправити">

</form>

Приклад 7.8a. Форма для приклада 7.8

Будемо впорядковувати дані, передані цією формою, по убуванню їхніх значень, зберігаючи при цьому значення ключів. Для цього зручно скористатися функцією arsort() . Оскільки нам важливий тільки новий порядок елементів, збережемо в новому масиві ключі вихідного масиву в потрібному порядку. Ми зберігаємо ключі вихідного масиву, оскільки вони є іменами елементів, з яких конструюється опис документа, а пам'ятати їх важливо. Отже, одержуємо такий скрипт:

<?php

print_r($_GET); echo "<br>";

arsort ($_GET);

// сортуємо масив у зворотному порядку, зберігаючи ключі

print_r($_GET); echo "<br>";

$ordered_names = array_keys($_GET);

// становимо новий масив

foreach($ordered_names as $key => $val)

echo "$key :$val <br>";

// виводимо елементи нового масиву

?>

Приклад 7.8b. Програма обробки форми із приклада 7.8


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

Очевидно, що може виникнути необхідність у сортуванні масиву за значеннями ключів. Наприклад, якщо в нас є масив даних про книги, як у наведеному вище прикладі, то цілком імовірно, що ми захочемо відсортувати книги по іменах авторів. Для цього в PHP також не потрібно писати багато рядків коду - можна просто скористатися функцією ksort() для сортування по зростанню (прямій порядок сортування ) або krsort() - для сортування по убуванню (зворотний порядок сортування ). Синтаксис цих функцій знову ж аналогічний синтаксису функції sort() .

<?php

$books = array("Пушкін"=>"Руслан і Людмила", "Толстой"=>"Війна й мир", "Лермонтов"=>"Герой нашого часу");

ksort($books);

// сортуємо масив, зберігаючи значення ключів

print_r($books);

?>

Приклад 7.9. Сортування масиву по ключах

Одержимо:

Array ( [Лермонтов] => Герой нашого часу

[Пушкін] => Руслан і Людмила

[Толстой] => Війна й мир )

Сортування за допомогою функції, заданої користувачем

Крім двох простих способів сортування значень масиву (по убуванню або по зростанню) PHP пропонує користувачеві можливість самому задавати критерії для сортування даних. Критерій задається за допомогою функції, ім'я якої вказується як аргумент для спеціальних функцій сортування usort() або uksort() . По назвах цих функцій можна догадатися, що usort() сортує значення елементів масиву, а uksort() - значення ключів масиву за допомогою заданої користувачем функції. Обидві функції повертають true, якщо сортування пройшло успішно, і false - у противному випадку. Їхній синтаксис виглядає в такий спосіб:

usort (масив , що сортує функція)

uksort (масив , що сортує функція)

Звичайно ж, не можна сортувати масив за допомогою будь-якої користувальницької функції. Ця функція повинна задовольняти певним критеріям, що дозволяють порівнювати елементи масиву. Як повинна бути влаштована функція, що сортує? По-перше, вона повинна мати два аргументи. У них інтерпретатор буде передавати пари значень елементів для функції usort() або ключів масиву для функції uksort() . По-друге, що сортує функція повинна повертати:

  • ціле число, менше нуля, якщо перший аргумент менше другого;

  • число, рівне нулю, якщо два аргументи рівні;

  • число більше нуля, якщо перший аргумент більше другого.


Як і для інших функцій сортування, для функції usort() існує аналог, що не змінює значення ключів, - функція uasort() .

Приклад 7.10. Допустимо, у нас є масив, що містить такі відомості про літературні твори, як назва, автор і рік створення. Ми хочемо впорядкувати книги по даті створення.

<?php

// масив виглядає в такий спосіб:

$books = array("Герой нашого часу" => array ("Лермонтов", 1840),

"Руслан і Людмила" => array("Пушкін",1820),

"Війна й мир" => array ("Толстой",1863),

"Ідіот" => array("Достоєвський",1868));

/* можна, звичайно переписати цей масив по-іншому, зробивши рік видання, наприклад, індексом, але набагато зручніше написати свою функцію для сортування */

uasort($books,"cmp");

// сортуємо масив за допомогою функції cmp

foreach ($books as $key => $book) {

echo "$book[0]: \"$key\"<br>";

}

function cmp($a,$b){

// функція, що визначає спосіб сортування

if ($a[1] < $b[1]) return -1;

elseif ($a[1]==$b[1]) return 0;

else return 1;

}

?>

Приклад 7.10. Сортування за допомогою користувальницьких функцій

У результаті одержимо:

Пушкін: "Руслан і Людмила"

Лермонтов: "Герой нашого часу"

Толстой: "Війна й мир"

Достоєвський: "Ідіот"

Ми застосували нашу власну функцію сортування до всіх елементів масиву. Далі розглянемо, як застосувати до елементів масиву будь-яку іншу користувальницьку функцію.

Застосування функції до всіх елементів масиву

Функція array_walk(масив, функція [, дані]) застосовує створену користувачем функцію до всіх елементів масиву масив і повертає true у випадку успішного виконання операції й false - у противному випадку.

Користувацька функція, як правило, має два аргументи, у які по черзі передаються значення й ключ кожного елемента масиву. Але якщо при виклику функції array_walk() зазначений третій аргумент, то він буде розглянутий як значення третього аргументу користувацької функції, зміст якого визначає сам користувач. Якщо функція користувача вимагає більше аргументів, чим у неї передано, то при кожному виклику array_walk() буде видаватися попередження.

Якщо необхідно працювати з реальними значеннями масиву, а не з їхніми копіями, варто передавати аргумент у функцію по посиланню. Однак потрібно мати на увазі, що не можна додавати або видаляти елементи масиву й робити дії, що змінюють сам масив, оскільки в цьому випадку результат роботи array_walk() уважається невизначеним.


<?php

$books1 = array("А.С. Пушкін"=>"Руслан і Людмила",

"Л.Н. Толстой"=>"Війна й мир",

"М.Ю. Лермонтов"=>"Герой нашого часу");

// створюємо функцію, що хочемо застосувати до елементів масиву

function try_walk($val,$key,$data){

echo "$data \"$val\" написав $key<br>";

}

// застосовуємо до всіх елементів масиву $books1 функцію try_walk

array_walk($books1,"try_walk","Роман");

?>

Приклад 7.11. Застосування функції до всіх елементів масиву

У результаті роботи скрипта одержимо:

Роман "Руслан і Людмила" написав А.С. Пушкіна

Роман "Війна й мир" написав Л.Н. Толстой

Роман "Герой нашого часу" написав М.Ю. Лермонтов

Помітимо, що ми не змінили значень елементів масиву. Щоб їх змінити, треба було передавати значення в змінну $val функції try_walk по посиланню.

<?php

$books1 = array(

"А.С. Пушкін"=>"Руслан і Людмила",

"Л.Н. Толстой"=>"Війна й мир",

"М.Ю. Лермонтов"=>"Герой нашого часу");

// створюємо функцію, що хочемо застосувати до елементів масиву

function try_walk(&$val,$key){

$key = "<p>Автор: " .$key ."<br>";

$val = "Назва: \"" . $val ."\"</p>";

echo $key.$val;

}

// застосовуємо до всіх елементів масиву $book1 функцію try_walk

array_walk($books1,"try_walk");

print_r($books1);

?>

Приклад 7.12. Застосування функції до всіх елементів масиву. Варіант 2

У результаті роботи скрипта одержимо:

Автор: А.С. Пушкін

Назва: "Руслан і Людмила"

Автор: Л.Н. Толстой

Назва: "Війна й мир"

Автор: М.Ю. Лермонтов

Назва: "Герой нашого часу"

Array ( [А.С. Пушкін] => Назва: "Руслан і Людмила"

[Л.Н. Толстой] => Назва: "Війна й мир"

[М.Ю. Лермонтов] => Назва: "Герой нашого часу")