Масиви в PHP (част 2) – custom ключове

В първа част на урока за работа с масиви говорихме за това как се създава нов, как можем да ги обхождаме с цикли (for и foreach) и това, че имат ключове.

Споменахме и, че във втора част ще говорим за това как ние сами да задаваме ключовете на елементите. Освен това ще огледаме и за някои предимства и недостатъци когато го правим.

PHP ни дава и възможност сами да определяме индексите на елементите в масива. Това става с една такава стрелкичка: =>.

Ръчно задаване на ключове

Ако например искаме да използваме горния масив, но „неделя“ да е с най-малък индекс (както е по американски), тогава бихме могли да напишем:

// елементите от масива са всеки на нов ред за
// по-добра четимост; няма проблем да ги пишем така
// няма да възникнат грешки
$days_of_week = array(
    1 => 'Monday',
    2 => 'Tuesday',
    3 => 'Wednesday',
    4 => 'Thursday',
    5 => 'Friday',
    6 => 'Saturday',
    0 => 'Sunday'
);

Не забравяйте, че елементите са с нулево индексиране – затова „понеделник“ е 1, а „неделя“ е номер 0.

Разлики в подредбата при for и foreach

Ако при горния масив използваме for цикъл – „неделя“ ще бъде първият ден в изходния код . Това е защото започваме с променлива със стойност 0. Но ако използваме foreach цикъл, PHP ще ни представи елементите в реда, в който са били дефинирани, без да ги подрежда по индекс. Това е една от особеностите в PHP.

Тъй като в повечето случаи искаме елементите да бъдат обработени в реда, в който са били дефинирани е по-добре да използваме foreach цикъл за обхождането им.

Напълно произволни числови индекси

Още повече, че при дефинирането на списък дори можем да прескочим някой елемент. Например, ако искаме да опишем само дните, в които ходим на фитнес, можем да използваме:

$gym_days = array(1 => 'Tuesday', 3 =>'Thursday');

В този пример имаме само два елемента – „вторник“ и „чeтвъртък“, но все пак сме запазили индексите, които отговарят на поредния им номер на ден от седмицата (ако тя започва в понеделник и е с нулево индексиране).

Така с foreach цикъл няма да имаме никакъв проблем, но с обикновен for цикъл още на елемент с номер 0 PHP ще ни изведе грешка, че се опитваме да достъпим недефиниран елемент. На всичкото отгоре и ако използваме count() за да определим до какъв максимален индекс трябва да увеличаваме променливата от for цикъла, това би ни върнало 2, тъй като има само 2 елемента в индекса, макар, че имаме елемент с индекс 3 и той дори няма да бъде достъпен.

Да речем, че все пак искаме да си усложним живота и не искаме да използваме foreach – какво можем да направим?

Някои функции за работа с масиви

Като за начало – нека определим максималния ключ в масива, така че да знаем до колко да броим.

Също така, нека определим и минималния, така че да не започваме с 0 (което вече казахме, че ще доведе до грешка), а да си започнем от стойност 1, която си е началната в този случай.

Защо просто не направим:

for ($i = 1; $i < 3; $i += 2) {
    ...
}

Защото това ще работи само и единствено с горния масив, а идеята е цикълът ни да е независим от структурата на масива. Така че след време, ако дните за фитнес се сменят, останалата част от кода да си остане същата. В противен случай – защо изобщо пишем програмен код? Нека просто си направим каквото искаме да правим с тия двата дена и да се свършва.

max() и min()

Тези две стойности можем да намерим съответно с функциите max() и min(). На тези две функции можем да пуснем неограничен брой аргументи и те ще ни върнат максималната/минималната стойност от него. Или можем да пуснем един аргумент, който да е масив. Той от своя страна може да има неограничен брой аргументи. Трябва да пуснем и втори аргумент функция. Функцията пак трябва да ни върне най-голямата / най-малката стойност.

Проблемът е, че ние в момента не търсим минимална и максимална стойност, а минимален и максимален ключ.

array_keys()

За щастие в PHP съществува функция, която използвайки един масив може да ни върне нов, който да съдържа като стойности ключове от първия. Разбирам, че това може да звучи объркващо, така че нека разгледаме един пример:

$gym_days = array(1 => 'Tuesday', 3 =>'Thursday');

$day_keys = array_keys($gym_days); // стойността на $day_keys ще е array(1, 3)

Надявам се така нещата да придобият някакъв елементарен смисъл.

След това вече можем да използваме функциите min() и max(), за да разберем коя е най-малката и коя е най-голямата стойност в този масив.

Сега вече можем да напишем:

$gym_days = array(1 => 'Tuesday', 3 =>'Thursday');

$day_keys = array_keys($gym_days);

$min = min($day_keys);
$max = max($day_keys);

echo '<ul>';

for ($i = $min; $i <= $max; $i++) {
    echo '<li>' . $gym_days[$i] . '</li>';
}

echo '</ul>';

Пак обаче остава проблемът с грешка в случая когато минем през стойността 2 (несъществуваща в този масив).

Проверка за съществуващ елемент

Това, което можем да направим е просто да проверим дали има такъв елемент и ако няма – да продължим с изпълнението на цикъла при следващата стойност:

$gym_days = array(1 => 'Tuesday', 3 =>'Thursday');

$day_keys = array_keys($gym_days);

$min = min($day_keys);
$max = max($day_keys);

echo '<ul>';

for ($i = $min; $i <= $max; $i++) {
    if (!isset($gym_days[$i])) {
        continue;
    }

    echo '<li>' . $gym_days[$i] . '</li>';
}

echo '</ul>';

continue

Ключовата дума continue в цикъла казва на PHP да прискочи тялото на цикъла и да продължи направо с изпълнението от следващата итерация (това, което би се случило със следващата стойност).

Можем да напишем просто:

...

for ($i = $min; $i <= $max; $i++) {
    if (isset($gym_days[$i])) {
        echo '<li>' . $gym_days[$i] . '</li>';
    }
}

което в този случай е същото. Но при по-дълго тяло и/или повече проверки, предходния израз може да е по-четим. Чрез него влизаме няколко нива по-навътре в индентация (друг път ще говорим, че стигнете ли вложени повече от 3 нива – нещо вероятно не е както трябва да бъде).

Очаквайте скоро част 3, в която ще видим още какви други custom ключове можем да използваме в PHP.

Един отговор за “Масиви в PHP (част 2) – custom ключове”

Вашият коментар

Вашият имейл адрес няма да бъде публикуван. Задължителните полета са отбелязани с *

Този сайт използва Akismet за намаляване на спама. Научете как се обработват данните ви за коментари.