Autor | Zpráva | ||
---|---|---|---|
nethor Profil |
#1 · Zasláno: 23. 1. 2015, 09:30:25
Zdravím,
mám asociativní pole $Arr = array( 'znacka' => 'object1', 'typ' => 'object2', 'model' => 'object3', ); a potřebuji podle indexu získat předchozí a následující index. Nedaří se mi najít funkci, která nastaví pointer na pozici podle indexu. Pak by se daly použít fce prev() a next(). Problém jde obejít pomocí foreach(), ale asi by to mělo jít jednodušeji. Poradíte? |
||
Keeehi Profil |
#2 · Zasláno: 23. 1. 2015, 10:02:31
|
||
nethor Profil |
#3 · Zasláno: 23. 1. 2015, 13:44:47
Keeehi:
To asi nepůjde použít u asociativního pole, když má být parametr integer. |
||
Dan Charousek Profil |
#4 · Zasláno: 23. 1. 2015, 13:57:20
Vlastní funkcí bych to řešil asi takto, ale je dost dobře možné, že existuje i jednodušší řešení:
function getNextAndPreviousKey(&$previous, $key, &$next, $array, $step = 1) { $keys = array_keys($array); $pos = array_search($key, $keys); $previous = isset($keys[$pos - $step]) ? $keys[$pos - $step] : null; $next = isset($keys[$pos + $step]) ? $keys[$pos + $step] : null; } $Arr = array( 'znacka' => 'object1', 'typ' => 'object2', 'model' => 'object3', ); $key = "typ"; getNextAndPreviousKey($previous, $key, $next, $Arr); echo " Previous key: $previous, value: $Arr[$previous]<br> Current key: $key, value: $Arr[$key]<br> Next key: $next, value: $Arr[$next] "; |
||
Alphard Profil |
nethor [#1]:
Lze si vytvořit funkci find(), která požadovaný prvek najde iteraci a pak používat prev() a next() dle potřeby. Dle vzoru prev a next s referencí. function find(&$arr, $key) { reset($arr); while (($k = key($arr)) !== null && $k !== $key) next($arr); } find($array, 'hledanyKlic'); echo next($array); echo next($array); Já bych se na tu referenci asi vykašlal a předával klasicky hodnotou, mně se to líbí víc. function find($arr, $key) { reset($arr); while (($k = key($arr)) !== null && $k !== $key) next($arr); return $arr; } Případně si to obalit do vlastní třídy. $storage->find('mujKlic')->getNext(); Dan Charousek [#4]: Jestli vám to vyhovuje, tak fajn, ale podle mě jsou s funkcemi s tolika parametry a ještě referencovanými jenom problémy. Když už bych měl mít podobně komplexní funkci, udělal bych samostatně prev a next verzi (která může být jen obálkou pro volání té současné). Edit: Doplnil jsem do těch funkcí ještě reset(). |
||
Dan Charousek Profil |
Alphard:
Možná jsem to s tím „Vlastní funkcí bych to řešil asi takto“ asi hodně nadsadil. Osobně bych preferoval nějakou pěknou obalovací třídu, ale bylo to první co mě napadlo a počítal jsem s tím, že se nebude jednat o ultimátní řešení. Ale zas na druhou stranu si myslím, že každý nápad hozený do ringu se počítá. Přeci jen může motivovat ostatní k ještě lepším řešením :). <?php class ArrWrapper { private $arr; public function __construct(Array $arr) { $this->arr = $arr; } public function findByKey($key) { // edit: Vzhledem k tomu, že je kód inspirován Alphardovo funkcí, také zde chyběl reset ^^ reset($this->arr); while(($k = key($this->arr)) !== null && $k !== $key) next($this->arr); return new ArrWrapper($this->arr); } public function getNext() {return next($this->arr);} public function getPrev() {return prev($this->arr);} } $arr = new ArrWrapper(array( "auto" => "Modré", "kolo" => "Zelené", "letadlo" => "Bílé" )); echo $arr->findByKey("auto")->getNext(); // Zelené echo $arr->findByKey("kolo")->getNext(); // Bílé echo $arr->findByKey("kolo")->getPrev(); // Modré |
||
nethor Profil |
#7 · Zasláno: 25. 1. 2015, 10:51:52
Díky,
WorkAround třída je docela překvápko, čekal jsem, že tyhle fce budou přímo někde v PHP... |
||
Alphard Profil |
nethor:
„WorkAround třída je docela překvápko“ Ona je to teda spíš funkce zabalená do třídy. Moje původní představa byla obálka nad datovým objektem, která bude mj. interně pracovat s ukazatelem na prvek pole bez neustálého kopírování samotného pole |
||
Časová prodleva: 9 let
|
0