Autor | Zpráva | ||
---|---|---|---|
jefitto44 Profil |
#1 · Zasláno: 11. 8. 2015, 14:44:55
Mám takéto pole
array (size=32) 23 => array (size=11) 'matchesWon' => int 6 'matchesLost' => int 10 'totalPlays' => int 16 'pointsScored' => int 154 'pointsConceded' => int 127 'homeWon' => int 4 'homeLost' => int 4 'awayWon' => int 2 'awayLost' => int 6 'touchB' => int 0 'touchA' => int 0 27 => array (size=11) 'matchesWon' => int 11 'matchesLost' => int 6 'totalPlays' => int 17 'pointsScored' => int 286 'pointsConceded' => int 134 'homeWon' => int 5 'homeLost' => int 3 'awayWon' => int 6 'awayLost' => int 3 'touchA' => int 0 'touchB' => int 0 Potrebujem ho zoradiť tak, aby hodnota "pointsScored" šla od najvyššej po najnižšiu. Mám na mysli, že celé položky poľa budú závisieť od veľkosť pointsScored, čiže najprv pojde index 27, až tak index 23. Tých položiek je tam samozrejme viac a ja to potrebujem sortnuť tak, aby poinstScored šlo od najväčšieho po najmenšie. Vie niekto pomôcť? |
||
juriad Profil |
#2 · Zasláno: 11. 8. 2015, 14:52:16
jefitto44:
Použij funkci uasort. <?php $data = array ( 23 => array ( 'matchesWon' => 6, 'matchesLost' => 10, 'totalPlays' => 16, 'pointsScored' => 154, 'pointsConceded' => 127, 'homeWon' => 4, 'homeLost' => 4, 'awayWon' => 2, 'awayLost' => 6, 'touchB' => 0, 'touchA' => 0, ), 27 => array ( 'matchesWon' => 11, 'matchesLost' => 6, 'totalPlays' => 17, 'pointsScored' => 286, 'pointsConceded' => 134, 'homeWon' => 5, 'homeLost' => 3, 'awayWon' => 6, 'awayLost' => 3, 'touchA' => 0, 'touchB' => 0, ) ); uasort($data, function($a, $b) {return $b['pointsScored'] - $a['pointsScored'];}); var_dump($data); |
||
jefitto44 Profil |
#3 · Zasláno: 12. 8. 2015, 08:46:43
Dal som presne toto, čo je v exampli na tej stránke a nefunguje.
1. Anonymna funkcia má 2 vstupné parametre. Keď ju volám, nemá žiadne parametre 2. Nikde neuvádzam, podľa ktorej hodnoty poľa to má sortovať. Som z toho magor a vôbec mi to nefunguje... na stack overflow som sa tiež nič rozumné nedočítal. Možno by bolo lepšie spraviť ten sort už v SQL? Ale to by bolo ešte zložitejšie... |
||
juriad Profil |
#4 · Zasláno: 12. 8. 2015, 08:54:24
jefitto44:
1. ty ji nemáš volat, volá ji funkce uasort. Ta funkce vrací kladné číslo, pokud má prvky prohodit. 2. uvádíš, v té anonymní funkci. Říkáš, že prvky má prohodit, pokud pointsScored druhého je větší než prvního (zapsané aritmeticky) Tento příklad mi funguje. Ukaž svůj kód, který ti dělá problémy. Ano, řazení v SQL je obvykle nejlepší nápad; ty jsi však vůbec nezmínil, že data pochází z databáze. |
||
jefitto44 Profil |
#5 · Zasláno: 12. 8. 2015, 09:10:22
function cmp($a, $b) { if ($a == $b) { return 0; } return ($a < $b) ? -1 : 1; } uasort($teamMatches, 'cmp'); var_dump($teamMatches);exit; Takto to mám a nefunguje mi to. Nerozumiem, čo to sú tie $a a $b parametre... niekde by som tam mal napísať, že pointsScored, alebo niečo také... vieš to plz opraviť? Chyba, ktorú hádže je uasort() expects parameter 2 to be a valid callback, function 'cmp' not found or invalid function name |
||
juriad Profil |
jefitto44:
Ta chybová hláška znamená, že uasort nevidí funkci cmp. Je definovaná v kontextu, kde je vidět? Není to náhodou metoda nějaké třidy? Mě totiž následující kód funguje: <?php $teamMatches = array(2 => 2, 4 => 4, 1 => 1); function cmp($a, $b) { if ($a == $b) { return 0; } return ($a < $b) ? -1 : 1; } uasort($teamMatches, 'cmp'); var_dump($teamMatches);exit; Ten komparátor bere jako parametry dva prvky a vrací číslo (kladné, záporné, nula) podle toho, zda jsou (správně, opačně, shodé). Můj komparátor je jednodušší: function cmp($a, $b) { # $a obsahuje, $b obsahuje -> výsledek # 100, 200 -> vrátí kladné číslo (prohodit) # 200, 100 -> vrátí záporné číslo (správné pořádí) # 100, 100 -> vrátí nulu (prvky jsou shodné / nezáleží na pořadí) return $b['pointsScored'] - $a['pointsScored']; } function cmp($a, $b) { if ($a['pointsScored'] == $b['pointsScored']) { return 0; } # všimni si prohozených znamének - chceš řadit sestupně return ($a['pointsScored'] < $b['pointsScored']) ? 1 : -1; } $a a $b jsou prvky pole, které řadíš. V případě pole, které jsi uvedl v [#1] jsou to ty vnitřní pole obsahující informace o hráčích (nebo co to vlastně je). V podstatě to nedělá nic víc než, že se pro každé dva prvky původního pole zeptá, který má být dřív. (Ehm, toto by bylo tupé a pomalé, ale výsledek je stejný.) Proč nepoužiješ anonymní funkci, jako jsem to udělal já? To máš snad verzi PHP starší než 5.3? |
||
jefitto44 Profil |
#7 · Zasláno: 12. 8. 2015, 09:30:47
Mám to v protected function... môže to byť ten problem?
protected function getBlaBla() { .... $teamMatches = array(2 => 2, 4 => 4, 1 => 1); function cmp($a, $b) { if ($a == $b) { return 0; } return ($a < $b) ? -1 : 1; } uasort($teamMatches, 'cmp'); var_dump($teamMatches);exit; } Nemôže byť klasická function v metode? |
||
juriad Profil |
#8 · Zasláno: 12. 8. 2015, 09:41:49
jefitto44:
„Nemôže byť klasická function v metode?“ Může, toto funguje. Nejspíš ještě něco zamlčuješ. <?php class Test { protected function prot() { $teamMatches = array(2 => 2, 4 => 4, 1 => 1); function cmp($a, $b) { if ($a == $b) { return 0; } return ($a < $b) ? -1 : 1; } uasort($teamMatches, 'cmp'); var_dump($teamMatches);exit; } public function call() { $this->prot(); } } $t = new Test(); $t->call(); Ale toto si bude stěžovat: <?php class Test { function cmp($a, $b) { if ($a == $b) { return 0; } return ($a < $b) ? -1 : 1; } protected function prot() { $teamMatches = array(2 => 2, 4 => 4, 1 => 1); uasort($teamMatches, 'cmp'); var_dump($teamMatches);exit; } public function call() { $this->prot(); } } $t = new Test(); $t->call(); Řešením je opravit způsob předání reference na cmp (protože to není funkce, ale metoda existujíci v kontextu objektu $this): uasort($teamMatches, array($this, 'cmp')); |
||
juriad Profil |
Přečti si php.net/manual/en/language.types.callable.php a pojednání o Passing. Tebe se jedná to „ A method of an instantiated object is passed as an array containing an object at index 0 and the method name at index 1.“
V tomto případě je však blbost mít cmp jako metodu; budeš ji snad používat i při jiných řázeních? Jelikož ona sama nezávisí na $this, měla by být alespoň privátní/protected statickou metodou. |
||
jefitto44 Profil |
Toto je skopírované tak ako to mám... getTeamStats($parameters) vráti pole ako je uvedené v prvom príspevku (teda 3D pole)
protected function getConferences($parameters) { $teamMatches = $this->getTeamStats($parameters); function cmp($a, $b) { if ($a == $b) { return 0; } return ($a < $b) ? -1 : 1; } uasort($teamMatches, 'cmp'); var_dump($teamMatches);exit; Tu je var dump celého poľa array (size=32) 27 => array (size=11) 'matchesWon' => int 11 'matchesLost' => int 6 'totalPlays' => int 17 'pointsScored' => int 286 'pointsConceded' => int 134 'homeWon' => int 5 'homeLost' => int 3 'awayWon' => int 6 'awayLost' => int 3 'touchA' => int 0 'touchB' => int 0 23 => array (size=11) 'matchesWon' => int 6 'matchesLost' => int 10 'totalPlays' => int 16 'pointsScored' => int 154 'pointsConceded' => int 127 'homeWon' => int 4 'homeLost' => int 4 'awayWon' => int 2 'awayLost' => int 6 'touchB' => int 0 'touchA' => int 0 26 => array (size=11) 'matchesWon' => int 10 'matchesLost' => int 6 'totalPlays' => int 16 'pointsScored' => int 247 'pointsConceded' => int 94 'homeWon' => int 4 'homeLost' => int 4 'awayWon' => int 6 'awayLost' => int 2 'touchA' => int 0 'touchB' => int 0 Moderátor Alphard: Zkráceno, kompletní výpis dat ničemu nepomůže.
|
||
Keeehi Profil |
#11 · Zasláno: 12. 8. 2015, 09:58:17
protected function getConferences($parameters) { $teamMatches = $this->getTeamStats($parameters); uasort($teamMatches, function($a, $b) {return $b['pointsScored'] - $a['pointsScored'];}); var_dump($teamMatches); exit; } A nebo nám ještě můžeš ukázat SQL. Neřekl bych, že to bude složité. |
||
jefitto44 Profil |
#12 · Zasláno: 12. 8. 2015, 10:04:46 · Upravil/a: jefitto44
ALELUJA! Ďakujem veľmi pekne, máš u mňa pivo ;)
SQL by bolo zložité, ide o to, že tieto hodnoty tam nemám a počítam ich v PHP až po výbere z DB... Celý mechanizmus vyzerá takto Query vyberie z DB informácie o jednotlivých zápasoch, ktoré sa hrali v danej season. NAsledovne sa počíta: team_A=team_B počet zápasov (totalMatches), čiže napočítavam v cykle +1 podľa toho, koľkokrát sa id tímu vyskytuje v team_A(home), alebo team_B(away) To isté platí pre score, napočítavam skore koľko dal team_A ak team_A je home ten, čo chcem a to isté pre team_B, čiže je to kus zložitejšie... ale v podstate mne šlo len o to sortnutie. Ďakujem veľmi pekne, si king :) |
||
tiso Profil |
#13 · Zasláno: 12. 8. 2015, 10:16:49
jefitto44: to by malo ísť vytiahnuť z databázy rovno.
|
||
juriad Profil |
jefitto44:
Vše co jsi popsal jde počítat už v databázi a myslím, že i poměrně jednoduše. Máš-li zájem ukaž jak vypadá tvé databázové schéma; zkusíme vymyslet dotaz, který vrátí záznamy podobně jako je máš v poli v [#1]. Jen prosím vysvětli, co znamená touchA a touchB. |
||
Keeehi Profil |
#15 · Zasláno: 12. 8. 2015, 10:22:25
jefitto44:
„ALELUJA! Ďakujem veľmi pekne, máš u mňa pivo ;)“ Kdybys nebyl ***** tak to co jsem napsal já ti napsal juriad už ve [#2]. Respektive moje celá práce byla, že jsem to odtamtud zkopíroval a obalil to metodou. Myslím, že bys měl dávat pozor a pečlivě zkoumat, co ti ostatní radí. Toto vlákno by pak mělo jen dva příspěvky. |
||
jefitto44 Profil |
#16 · Zasláno: 12. 8. 2015, 10:36:34 · Upravil/a: jefitto44
No upravil som si to kus takto
uasort($teamMatches, function($a, $b) {return ($b['matchesWon'] / $b['totalPlays']) - ($a['matchesWon'] / $a['totalPlays']);}); V skutočnosti som pre zjednodušenie trošku luhal. Nepotrebujem to radiť podľa totalPoints, ale podľa winPercentage. Tá sa počíta tak, že sa vezme počet vyhraných matchov a vydelí sa celkovým počtom odhratých matchov. KeĎ to napíšem takto, zoradí mi to naopak, od najmenšieho po najväčší a ani panovi sa to neda zoradiť naopak. T,. nefunguje na to array reverse, ani nepomôže ak dám najpv $b - $a Teraz na to pozerám a s hrôzou zisťujem, že mi to nezoradilo korektne... z nejakých dôvodov mi to nahádzalo ako prišlo... Vyzerá, že to zoradilo proste len prvé dva indexy a konec Ktorý *** vymyslel to php? Prečo tam proste nemôže byť funckia array_sort_value($array, $value, $direction) a napísal by som proste array_sort_value($teamStats, "totalScores", "DESC") a bolo by hotovo? |
||
Kcko Profil |
#17 · Zasláno: 12. 8. 2015, 10:46:47
jefitto44:
„Ktorý *** vymyslel to php? Prečo tam proste nemôže byť funckia array_sort_value($array, $value, $direction) a napísal by som proste array_sort_value($teamStats, "totalScores", "DESC") a bolo by hotovo?“ Někdo mnohem chytřejší než ty, když máš problém zadrátovat funkční kód ... který Ti byl porazen už na začátku topicu, ach jo ... |
||
juriad Profil |
jefitto44:
Nikdo netušil, že chceš porovnávat desetinná čísla. Viz php.net/manual/en/function.usort.php to velké varování „Returning non-integer values from the comparison function, such as float, will result in an internal cast to integer of the callback's return value. So values such as 0.99 and 0.1 will both be cast to an integer value of 0, which will compare such values as equal.“ Změň ten komparátor na toto. Pak bude počítat jen s celými čísly a vše bude fungovat. A zamysli se, proč je toto ekvivalentní (práci se zlomky a nejmenšími společnými jmenovateli snad zvládáš). return ($b['matchesWon'] * $a['totalPlays']) - ($a['matchesWon'] * $b['totalPlays']); „Ktorý *** vymyslel to php? Prečo tam proste nemôže byť funckia array_sort_value($array, $value, $direction) a napísal by som proste array_sort_value($teamStats, "totalScores", "DESC") a bolo by hotovo?“ Ten, který byl tak chytrý, že věděl, že nemá smysl vytvořit tisíce funkcí, ale raději jednu univerzální. Kdybys chtěl řadit podle těchto procent, očekával bys funkci array_sort_value_ratio($array, $nominator, $denominator, $direction) ?
|
||
jefitto44 Profil |
#19 · Zasláno: 12. 8. 2015, 10:56:33
Ale ja potrebujem počítať len s desatinnými, nakoľko táto hodnota sa bude pohybovať 0-1 (0 ak tím nevyhraje nai jeden zápas a 1 ak vyhraje všetky). Sú to proste percentá 0-100% <=> 0-1 a medzitým, napr. 50% je 0.5 a toto ja potrebujem porovnávať a zoradiť podľa toho
|
||
tiso Profil |
#20 · Zasláno: 12. 8. 2015, 11:00:09
jefitto44:„Prečo tam proste nemôže byť funckia array_sort_value($array, $value, $direction)“
Môže a dá sa vytvoriť, ako každá iná vlastná funkcia. Ale nemôžeš od PHP chcieť aby malo každú funkciu ktorú potrebuješ. „Ale ja potrebujem počítať len s desatinnými, nakoľko táto hodnota sa bude pohybovať 0-1“ A kto ti bráni? |
||
jefitto44 Profil |
#21 · Zasláno: 12. 8. 2015, 11:02:04
Bráni mi php manual
„Returning non-integer values from the comparison function, such as float, will result in an internal cast to integer of the callback's return value. So values such as 0.99 and 0.1 will both be cast to an integer value of 0, which will compare such values as equal.“ |
||
Keeehi Profil |
jefitto44:
Ach jo, a je to tady zase. Příspěvek [#18] je zase správné řešení. Ale místo toho, aby jsi to zkusil, tak tu budeš psát o tom, že potrebuješ porovnávat desetinná čísla. Což není pravda jak juriad dokázal. Matematika je mocná, tak se ji nauč, budeš ji v životě potřebovat. Moderátor juriad: Příspěvek jsem průběžně upravoval k doknalosti, nemám mu za zlé, že si třeba nevšiml úpravy.
|
||
jefitto44 Profil |
#23 · Zasláno: 12. 8. 2015, 11:11:04 · Upravil/a: jefitto44
Však dobre, ale nebude mi to rátať kraviny? Tam v podstate ide len o porovnanie dvoch čísel, teda teoreticky by to mohlo fungovať?
Takto mi to nefunguje korektne... team1: totalplays - 19 z toho 13 víťazných = 0,684 ALE 19*13=247 team2: totalplays - 17 z toho 14 víťazných = 0,824 ALE 17*14=238 čiže mi to nezoradí korektne... |
||
juriad Profil |
#24 · Zasláno: 12. 8. 2015, 11:19:38
jefitto44:
Ty ale nenásobíš čísla patřící jednomu záznamu, ale násobíš záznamy křížem. V tom je ten trik. team1: totalplays - 19 z toho 13 víťazných = 0,684 ALE 13*17=221 team2: totalplays - 17 z toho 14 víťazných = 0,824 ALE 14*19=266 |
||
juriad Profil |
jefitto44:
Chceš-li, klidně si ten komparátor uprav ternárními výrazy, aby vracel -1, 0, 1. $diff = ...; # nějaký výpočet s desetinnými čísly. return $diff == 0 ? 0 : ($diff > 0 ? 1 : -1); |
||
Keeehi Profil |
#26 · Zasláno: 12. 8. 2015, 11:25:27
jefitto44:
A co kdyby jsi konečně uznal, že tu jsou lidé, kteří mají zkušenosti* a kterým by jsi mohl věřit, že když ti něco poradí, tak to v 99% případů bude správně. A ne, krajiny to počítat nebude. Mohl bych ti sepsat i matematický důkaz ale byl bych rád, kdyby jsi mě tím nezatěžoval. Můj čas je drahý a nerad bych ho strávil psaním důkazů který si můžeš napsat sám. Podle tvých webovek máš základku i střední za sebou, tak bys to měl zvládnou. Dokonce jsi studoval na učitele fyziky. Jestli máš problém i s takto základní matematikou tak se nedivím, že jsi zkončil. * jsi tu dost dlouho na to, abys věděl, kdo tu často dává dobré rady. |
||
jefitto44 Profil |
#27 · Zasláno: 12. 8. 2015, 12:32:11
Konečne mi to funguje.
Keeehi, Ďakujem za podceňovanie, posúva ma to vpred :) |
||
Časová prodleva: 10 let
|
0