Slovník pojmů

Cyklus v programování

Cyklus opakuje kód pro kolekci nebo do splnění podmínky. Musí být jasné, co tvoří jednu iteraci, kdy skončí a zda se během ní nemění data, která právě prochází.

Stručná definice

Opakování s viditelným ukončením.

Iterace je jedno provedení těla cyklu. Zdroj prvků bývá pole, rozsah čísel nebo stav řízený podmínkou. Cyklus není rekurze: rekurze znovu volá funkci a potřebuje základní případ, zatímco cyklus opakuje blok v jedné konstrukci.

Počet iterací není automaticky index pole. U souvislého seznamu jsou indexy běžně od nuly, ale například PHP array může mít nesouvislé klíče. Proto je foreach často bezpečnější vyjádření práce s položkami než ruční počítadlo.

Jaký problém řeší

Zpracuje každou položku bez opakování stejného zápisu.

Cyklus se používá pro součet objednávky, vykreslení seznamu, práci s dávkou nebo procházení validovaných dat.

  • součet cen položek objednávky
  • zpracování výsledků API nebo importu
  • vykreslení kolekce ve frontendovém rozhraní
  • opakování akce, dokud nenastane definovaný konec

Praktický příklad

Součet položek objednávky pomocí foreach

foreach vyjadřuje, že chceme pracovat s každou položkou kolekce, ne s indexem. Částky jsou v haléřích, takže ukázka neřeší chybu plovoucí čárky. Pracuje již s validovanými položkami přesně popsaného tvaru.

Pokud položky leží v databázi, není vždy vhodné provést pro každou další dotaz. U většího objemu zvažte přednačtení nebo hromadnou databázovou operaci podle business pravidel.

PHP

/** @param list<array{quantity: positive-int, unitPriceInCents: int}> $items */
function calculateItemsTotal(array $items): int
{
    $totalInCents = 0;

    foreach ($items as $item) {
        $totalInCents += $item['quantity'] * $item['unitPriceInCents'];
    }

    return $totalInCents;
}

Jak funguje

Průchod položkami objednávky

Přístupný diagram ukazuje nejběžnější případ kolekce.

  1. Začátek Součet má počáteční hodnotu nula.
  2. Další položka Cyklus vezme jednu hodnotu z kolekce.
  3. Tělo cyklu Připočítá řádkovou cenu do součtu.
  4. Ukončení Po poslední položce vrátí výsledek.

Hlavní části a varianty

for, foreach a while nevyjadřují totéž.

Volba konstrukce má popsat, co řídí opakování.

for

Hodí se pro známý rozsah nebo počítadlo, když má index skutečný význam.

foreach

Prochází prvky kolekce a obvykle nezavádí chybu v ručním indexu.

while a do while

while ověřuje podmínku před tělem, do while jej provede alespoň jednou.

break a continue

break cyklus ukončí, continue přeskočí jen aktuální iteraci; jejich záměna mění výsledek.

Omezení a časté chyby

Opakování může růst rychleji, než je vidět.

Co pomáhá

  • vybrat foreach pro kolekci a for jen při významném indexu
  • zviditelnit podmínku ukončení
  • zvlášť testovat prázdnou i hraniční kolekci

Rizika

  • while bez ověřitelného ukončení
  • i <= count($items) jako off-by-one u souvislého seznamu
  • změna kolekce během iterace
  • vnořené cykly nebo databázový dotaz v každé iteraci bez měření

Praktické použití

Pohodlný zápis nesmí skrýt cenu provedení.

Vnořené cykly mohou násobit práci s daty. To není automaticky chyba, ale u větších kolekcí je potřeba znát objem, provést měření a případně změnit algoritmus nebo práci s databází.

Nekonečný cyklus může být záměrný například v event loopu nebo workeru, musí však mít řízené blokování, obsluhu selhání a způsob ukončení procesu.

Změna kolekce během iterace může podle jazyka a použité konstrukce přeskočit prvek nebo vytvořit nečekaný stav. Je proto vhodné nejdřív určit, zda se má pracovat se snímkem dat, vytvořit nová kolekce, nebo změnu odložit až po průchodu. U ručního indexu je nutné rozlišit počet prvků od posledního platného indexu; u souvislého seznamu je poslední index count($items) − 1.

Cyklus bývá jen jedním krokem algoritmu. Je-li v každé iteraci databázový dotaz, může vzniknout N+1 problém; někdy pomůže přednačtení dat nebo hromadná operace. Správná volba ale závisí na pravidlech, objemu i čitelnosti, proto ji nelze nahradit slepým zákazem všech vnořených cyklů.

break má ukončit pouze cestu, kdy už další položky nemohou změnit výsledek. continue je vhodné jen tehdy, když je srozumitelné, proč se jedna položka přeskočí. Pokud se takové rozhodování opakuje, může být čitelnější data nejdřív filtrovat nebo pravidlo vyjmout do pojmenované funkce.

U zpracování velké dávky má každá iterace také provozní dopad. Je vhodné rozhodnout, zda se chyba jedné položky zapíše a dávka pokračuje, nebo se práce ukončí a může bezpečně navázat od posledního potvrzeného bodu. Takové pravidlo není vlastností for ani foreach, ale způsob určení ukončení a práce s chybou rozhoduje o spolehlivosti celého procesu.

Kontrola změny

Každé opakování má mít důvod a konec.

Cyklus je bezpečnější, když z kódu vyčtete zdroj prvků, stav změny a ukončení.

  • ověřit prázdnou kolekci a poslední iteraci
  • neplést počet iterací s indexem nebo klíčem
  • používat break jen pro skutečné ukončení
  • vyhnout se N+1 dotazům v opakování

Časté otázky

Cyklus v praxi

Kdy použít for a kdy foreach?

foreach pro prvky kolekce, for pokud potřebujete rozsah nebo index jako součást pravidla.

Jaký je rozdíl mezi break a continue?

break ukončí celý aktuální cyklus, continue přeskočí jen zbytek jedné iterace.

Je každý nekonečný cyklus chyba?

Ne, ale musí být záměrný a provozně řízený.

Je cyklus totéž co rekurze?

Ne. Rekurze opakuje volání funkce, cyklus opakuje blok kódu.

Osobní zkušenost

Opakované zpracování musí zůstat přehledné i nad většími daty.

V PHP aplikacích volím cykly podle tvaru dat a sleduji jejich dopad na databázové operace i výkon.

Zavolejte mi

Zavolám vám následující pracovní den mezi 9:00 a 17:00.

Můžete mi také zavolat rovnou.

+420 605 181 728

Nechte mi telefonní číslo a pošlete žádost o zpětné zavolání.

Odesláním souhlasíte se zpracováním údajů pro vyřízení žádosti.