Zjištění příslušnosti do seznamu

Školení, která pořádám

Pokud chceme zjistit, jestli proměnná odpovídá nějakému prvku v seznamu, můžeme to udělat několika způsoby:

<?php
($a == "a" || $a == "b" || $a == "c" || $a == "d");
in_array($a, array("a", "b", "c", "d"));
preg_match('~^(a|b|c|d)$~', $a);
?>

První způsob je dlouhý na zápis a neumožňuje prvky seznamu definovat mimo samotnou podmínku např. v proměnné. Používám ho tedy pouze v případě, že seznam má pouze dva, maximálně tři prvky a $a není volání funkce. Druhý způsob bych označil za tradiční řešení a třetí způsob je sice poněkud hůře čitelný, ale má tu výhodu, že prvky seznamu mohou být nejen konstantní řetězce, ale i regulární výrazy. Pokud je seznam definován mimo podmínku a je dlouhý, stojí za zvážení uložit prvky jako klíče pole a následně testovat isset($prvky[$a]), což by mělo být teoreticky rychlejší, protože vypočtení hashe a přímý přístup k prvku je rychlejší než procházení celého pole funkcí in_array. Především v Céčkových zdrojácích je možné vidět také následující způsob, kvůli jeho neúspornosti ale nejsem jeho zastáncem.

<?php
switch ($a) {
    case 'a':
    case 'b':
    case 'c':
    case 'd':
        ;
}
?>
Jakub Vrána, Dobře míněné rady, 14.9.2005, diskuse: 7 (nové: 0)

Diskuse

Lukas:

Ja celkem casto pouzivam switch a nevidim v tom nic horsiho nez zapis in_array nebo preg_match.

Z jakeho duvodu nejsi jeho zastancem (switch)?

Llaik:

Mozna proto, ze zabira dost mista.. na druhou stranu  bych tipl, ze switch ze vsech reseni bude mozna nejrychlejsi, ne? (coz je ve vetsine pripadu phpka docela putna,ale.. :))

ikona Jakub Vrána OpenID:

Přesně tak, je s tím hodně psaní a nezdá se mi to ve většině případů přehledné. O rychlostní rozdíly v řádu procent až tak nejde (http://php.vrana.cz/optimalizace-kodu.php), prvořadá je pro mě čitelnost a rozšiřitelnost.

TimeLord:

"switch" je podla mna citatelny viac nez dost a je rychlejsi.

Zalezi samozrejme od sposobu pouzitia, niekde sa viac hodi "switch", inde "if".

Na druhej strane, robit jednoznacne prehlasenie, ze "switch a nic ine" by bolo zase unahlene.

johno:

Ak je ten zoznam fakt dlhé, tak to robím takto:
<?php
    $list
= array(
        "a" => 1,
        "b" => 1,
        "c" => 1,
        // ...
    );
   
    $isThere
= array_key_exists($a, $list);
?>

Je to potom oveľa rýchlejšie, pretože nemusím ísť lineárne O(n) cez pole, ale cez hash a teda konštantne O(1). Opakujem, toto zrýchlenie sa poriadne prejaví až pri veľkých poliach. Rádovo tak od stovky alebo tisícovky položiek.

ikona Jakub Vrána OpenID:

Ano, je to zmíněné i v článku, pouze místo array_key_exists($a, $list) je použito isst($list[$a]).

johno:

Aha, pardón.

Vložit komentář

Používejte diakritiku. Vstup se chápe jako čistý text, ale URL budou převedeny na odkazy a PHP kód uzavřený do <?php ?> bude zvýrazněn. Pokud máte dotaz, který nesouvisí s článkem, zkuste raději diskusi o PHP, zde se odpovědi pravděpodobně nedočkáte.

Jméno: URL:

avatar © 2005-2018 Jakub Vrána. Publikované texty můžete přetiskovat pouze se svolením autora. Ukázky kódu smíte používat s uvedením autora a URL tohoto webu bez dalších omezení Creative Commons. Můžeme si tykat. Skripty předpokládají nastavení: magic_quotes_gpc=Off, magic_quotes_runtime=Off, error_reporting=E_ALL & ~E_NOTICE a očekávají předchozí zavolání mysql_set_charset. Skripty by měly být funkční v PHP >= 4.3 a PHP >= 5.0.