Autor | Zpráva | ||
---|---|---|---|
Bobeš Profil * |
#1 · Zasláno: 23. 9. 2011, 00:13:35
Zdravíčko,
poradí mi někdo jak opakovaně vybrat prvky na n-té pozici v poli. Řekněme, že mám pole o obsahu zhruba několik set prvků a potřebuju vyfiltrovat třebas každý čtvrtý, osmý, dvanáctý... atakdále prvek a ty pak vložit do jiného pole bo řetězce k dalšímu zpracování. Ať hledám, jak hledám... |
||
ShiraNai7 Profil |
#2 · Zasláno: 23. 9. 2011, 00:22:19
// testovaci pole $pole = array(); for($i = 1; $i <= 100; ++$i) $pole[] = $i; // funkce function arrayGetNth($arr, $n) { $output = array(); $arr_size = sizeof($arr); $i = $n - 1; while($i < $arr_size) { $sl = array_slice($arr, $i, 1); $output[] = $sl[0]; $i += $n; } return $output; } // test print_r(arrayGetNth($pole, 4)); // kazdy 4ty prvek Vysledkem je: Array ( [0] => 4 [1] => 8 [2] => 12 [3] => 16 [4] => 20 [5] => 24 [6] => 28 [7] => 32 [8] => 36 [9] => 40 [10] => 44 [11] => 48 [12] => 52 [13] => 56 [14] => 60 [15] => 64 [16] => 68 [17] => 72 [18] => 76 [19] => 80 [20] => 84 [21] => 88 [22] => 92 [23] => 96 [24] => 100 ) |
||
Majkl578 Profil |
#3 · Zasláno: 23. 9. 2011, 00:50:30
[#2] ShiraNai7:
To je poměrně nešikovná funkce provádějící zbytečné (ne-li nesmyslné) úkony. Existují i jednodušší a transparentnější řešení, například: $data = range(50, 1000, 5); // vstupní data $step = 4; // krokování $selector = function (array $array, $step) { $i = 0; return array_filter($array, function ($item) use ($step, &$i) { return ++$i % $step === 0; }); }; var_dump($selector($data, $step)); //4., 8., 12. atd. |
||
ShiraNai7 Profil |
#4 · Zasláno: 23. 9. 2011, 00:58:08
Majkl578:
„To je poměrně nešikovná funkce provádějící zbytečné (ne-li nesmyslné) úkony.“ Výsledek je stejný, co je na tom nesmyslného? |
||
Majkl578 Profil |
#5 · Zasláno: 23. 9. 2011, 01:09:01
ShiraNai7:
Celý ten while cyklus dělá zbytečné úkony, konkrétně řádky 12 a 13 jsou zbytečný nesmysl. Nehledě na to, že tvé řešení nezohledňuje původní klíče ve výsledku (což sice nemusí být nutné, ale rozhodně je to vhodné). |
||
ShiraNai7 Profil |
#6 · Zasláno: 23. 9. 2011, 01:35:30 · Upravil/a: ShiraNai7
Majkl578:
„Celý ten while cyklus dělá zbytečné úkony, konkrétně řádky 12 a 13 jsou zbytečný nesmysl.“ Jak jinak bez funkce array_filter vybrat ntý prvek z pole (které může obsahovat číselné i jiné indexy)? Nijak. A nepředpokádám že Bobeš používá verzi PHP 5.4+ kde bych mohl úplně vynechat přiřazování ( $output[] = array_slice($arr, $i, 1)[0]; ) |
||
joe Profil |
#7 · Zasláno: 23. 9. 2011, 03:06:24
Nelíbí se mi ani jedno řešení, proto přidávám moje, které je zároveň nejrychlejší ze zde uvedených (zatím jsem se moc nezžil s používáním closures v PHP) a nevím proč dělat věci složitě, když to jde jednoduše :)
function arrayNth(array $array, $n) { $output = array(); $i = 0; foreach($array as $key => $value) { if(++$i % $n === 0) $output[$key] = $value; } return $output; } ShiraNai7: „Výsledek je stejný“ Výsledek asi stejný bude, ale to tvé řešení pokulhává už při 100000 záznamech v poli. |
||
ShiraNai7 Profil |
#8 · Zasláno: 23. 9. 2011, 09:43:21
joe:
Moc rychlé to asi nebude, proč mě nenapadl obyčejný foreach nevím, možná protože bylo půl jedné ráno :) |
||
Bobeš Profil * |
#9 · Zasláno: 23. 9. 2011, 19:28:46
Díky za řešení pánové ;-)
|
||
Majkl578 Profil |
#10 · Zasláno: 23. 9. 2011, 20:54:36
Dobře tedy, když jsme už se dostali ke srovnávání složitosti, porovnal jsem jednotlivé funkce.
Použil jsem totožný script na 20 tisíc stejných záznamů v poli nechal vypsat čas a maximum užité paměti: $data = range(1, 2e4); $start = microtime(TRUE); // funkce // a volání funkce echo microtime(TRUE) - $start; echo PHP_EOL; echo memory_get_peak_usage(); echo PHP_EOL; Výsledky jsou následující: ShiraNai7: 5.301s, 3.576 MB Majkl578: 0.174s, 3.577 MB joe: 0.068s, 5.307 MB ShiraNai7 zde může vidět, proč je jeho řešení naprosto nepoužitelné. Řešení od joa je sice nejrychlejší, nicméně o 2/3 paměťově náročnější. |
||
joe Profil |
#11 · Zasláno: 24. 9. 2011, 11:27:02
Majkl578:
To je zajímavý :) Tak jsem se aspoň trochu poučil, díky. Ale nějak nechápu proč ten foreach zabere víc paměti než ten array_filter, co vlastně taky prochází celé to pole, ne? |
||
Časová prodleva: 13 let
|
0