Prohození prvků

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

Dopsal jsem knihu

Pokud potřebujeme prohodit hodnotu dvou prvků, lze to řešit přes pomocnou proměnnou:

<?php
$pom = $a;
$a = $b;
$b = $pom;
?>

Elegantnější mi nicméně přijde pro tuto operaci použít konstrukci list, která do svých parametrů přiřadí prvky z pole na pravé straně přiřazení:

<?php
list($a, $b) = array($b, $a);
?>
Jakub Vrána, Výuka, 27.9.2006, diskuse: 21 (nové: 0)

Diskuse

Michalek:

Zajímavý, logický, ale samotnýho by mě to nenapadlo... Dík moc, hodí se.
# 27.9.2006 02:13:38 reagovat

ikona dgx:

Praví, drsní a assemblerem ošlehaní hackeři používají výhradně:
<?php
$a
^= $b;
$b ^= $a;
$a ^= $b;
?>
(funguje pro celá čísla a stejně dlouhé řetězce) :-)
# 27.9.2006 02:23:02 reagovat

tracy:

Kdepak. Pravý, drsný a assemblerem ošlehaný hacker by použil:
<?php
$a
^= $b ^= $a ^= $b;
?>
# 27.9.2006 02:58:33 reagovat

ikona dgx:

:-)) Ten zápis má dokonce i estetické přednosti.

Jinak ti nejošlehanější píšou zásadně v bytecode:
FETCH_R        $3, 'b'
FETCH_RW       $2, 'a'
ASSIGN_BW_XOR  $4, $2, $3
FETCH_RW       $1, 'b'
ASSIGN_BW_XOR  $5, $1, $4
FETCH_RW       $0, 'a'
ASSIGN_BW_XOR  $0, $5

# 27.9.2006 03:19:17 reagovat

Pavel:

A Ti nej nej borci si to nechají naprogramovat :)
# 27.9.2006 09:30:06 reagovat

Llaik:

nene, ti nejvetsi borci chodi na php.vrana.cz a prectou si hotova reseni :)
# 27.9.2006 11:07:14 reagovat

RATMex B:

Áno, bežne sa to používalo ako macro, pretože na úrovni JSI sa s ničím iným, ako "sledom bitov", nepracovalo a sprehľadňoval sa tým kód.
Lenže v PHP sú okrem integeru (a booleanu) aj ďalšie typy, s ktorými to fungovať nebude.
# 27.9.2006 11:49:46 reagovat

johno:

Alebo si spraviť funkciu function swap(&$a, &$b) { $tmp = $a; $a = $b; $b = $tmp; }
# 27.9.2006 13:17:22 reagovat

Juro Hajdúch:

a aby som sa zbavil $tmp:
<?php
function swap(&$a, &$b) { list($a, $b) = array($b, $a); }
?>
# 27.9.2006 19:43:22 reagovat

ikona dgx:

Řešení pomocí list() je o 80% pomalejší!

(to je prostě parádní odborná pitva nejbanálnějšího programátorského úkonu, který se navíc skoro nikdy nepoužívá :-))
# 27.9.2006 21:04:01 reagovat

v6ak:

ona se tam jakože nepoužívá pomocná proměnná, ale ve skutečnosti jo.
# 9.10.2006 18:18:53 reagovat

PIF:

aspoň jsme se zase sterilně zasmáli :) každopádně krása se tomu upřít nedá.
# 28.9.2006 21:19:49 reagovat

ikona MiSHAK:

Wow!
# 2.10.2006 06:46:38 reagovat

Ondra:

V patek jsme to resili v algortmizaci (co porada nas gympl), byl jsem uspesnym resitelem s timto kodem:

$a = $a+$b;
$b = $a-$b;
$a = $a-$b;

Pisu to z hlavy tak ze mne laskave po(o)pravte jestli je to spatne. To mi prijde nejelegantnejsi reseni, bez zadnych binarnich operaci, bez jinych funkci.
# 2.10.2006 15:00:56 reagovat

Fak:

ale co řetězce?
# 8.10.2006 00:55:56 reagovat

Squad_Leader:

Už to nehulte :-D  Nedělá vám to dobře.
# 14.10.2006 20:26:43 reagovat

v2j:

re: {$tmp = $a; $a = $b; $b = $tmp;}

Trochu problém bych viděl v tom, že v momentě, kdy se změní reference $a, PHP vytvoří pro $tmp klon prvku, což by mohlo vadit. Třeba v prohazování polí, kdy se naprosto zbytečně vytváří paměťová kopie celého pole a naopak originál zruší. Náročný na paměť i čas.

Uvažuju správně? Ale stejně nejlepší řešení bude přes list(), přesně to jsem hledal ;-)
# 4.4.2009 06:15:40 reagovat

ikona v6ak:

// Snad ten workaround s Operou mini pojede.
Pokud proměnné a a b jsou objekty, pak ve starém PHP4 dojde ke klonování objektu (vpodstatě kopírování, nevím, jak to je s vnitřními vlastnostmi), ale v PHP5 pouze ke kopírování odkazů (teď si nejsem jist, jestli to je zde správný termín).
# 4.4.2009 06:40:34 reagovat

ikona v6ak:

Tak ještě drobné OT: Pokud v Opeře mini před vložením příspěvku reloadnu (#0) a pak teprve stisknu reagovat, pak reakce fungují dobře.
# 4.4.2009 06:44:01 reagovat

ikona Jakub Vrána:

Vzhledem k tomu, že PHP používá copy-on-write, tak přiřazení libovolně velké proměnné je operace s konstantním časem.
# 4.4.2009 18:37:07 reagovat

ikona v6ak:

To je vlastně taky pravda. Já to bral jen z logiky php programátora.
Dodám odkazy:
* http://latrine.dgx.cz/php-puvab-optimalizace-rychlosti
* http://latrine.dgx.cz/php-cerna-magie-optimalizace
# 5.4.2009 02:42:11 reagovat

Vložit příspěvek

Používejte diakritiku. Nelze používat HTML značky, 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:

© 2005-2010 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.