Prohození prvků
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); ?>
Diskuse
Michalek:
Zajímavý, logický, ale samotnýho by mě to nenapadlo... Dík moc, hodí se.
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) :-)

tracy:
Kdepak. Pravý, drsný a assemblerem ošlehaný hacker by použil:<?php
$a ^= $b ^= $a ^= $b;
?>
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

Pavel:
A Ti nej nej borci si to nechají naprogramovat :)Llaik:
nene, ti nejvetsi borci chodi na php.vrana.cz a prectou si hotova reseni :)
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.
johno:
Alebo si spraviť funkciu function swap(&$a, &$b) { $tmp = $a; $a = $b; $b = $tmp; }
Juro Hajdúch:
a aby som sa zbavil $tmp:<?php
function swap(&$a, &$b) { list($a, $b) = array($b, $a); }
?>
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á :-))

v6ak:
ona se tam jakože nepoužívá pomocná proměnná, ale ve skutečnosti jo.PIF:
aspoň jsme se zase sterilně zasmáli :) každopádně krása se tomu upřít nedá.
MiSHAK:
Wow!

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.
Fak:
ale co řetězce?Squad_Leader:
Už to nehulte :-D Nedělá vám to dobře.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 ;-)
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).

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.

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.


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

Diskuse je zrušena z důvodu spamu.

