Miten saan PHP:ssä taulukon järjestettyä eniten pisteitä saanut ensimmäisenä?
$nimi[$pisteet]
Eli pitäisi saada järjestettyä pisteiden mukaan suurimmasta pienempään.
Olen etsinyt netistä, mutta huonolla menestyksellä tai sitten en vain ymmärrä.
ksort($nimi);
$nimet=file("nimet.txt");// pelaajien nimet $maara = count($nimet);// pelaajien lukumäärä for($i=0; $i<$maara; $i++){ $nimi=trim($nimet[$i]); $pisteet=file_get_contents($nimi."/yhpisteet".".txt"); $nimi[$i]=$pisteet; } ksort($nimi);
En tiedä missä mättää, mutta tuo koodi ei järjestä taulukkoa pisteiden mukaan suurimmasta pienimpään. Ei järjestä sitä mitenkään vaan tulostuu siinä järjestyksessä miten nimet on tiedostossa. Taulukko tulostuu muutoin oikein, mutta tuo järjestäminen ei onnistu.
Lisäys: ai niin, unohtu laittaa mukaan virheilmoitus minkä tuo koodi antaa: Warning: ksort() expects parameter 1 to be array, string given in /home/xxxxxx/public_html/pelit/parhaat.php on line 29
jos nopeasti analysoin niin:
- $nimi korvaantuu joka kierros uudella arvolla [for-loopin 1. rivi]
- $nimi ei ole taulukko mielestäni [for-loopin viimeinen rivi], miksi sama muuttujan nimi?
toimisiko jos nimet laitetaisiin vaikkapa $nimet_2 -taulukkoon
$nimet_2 = []; // for:ssa $nimet_2[] = $pisteet; ksort($nimet_2);
Kannattaa ehkä ensin miettiä koodin rakenne kuntoon. Missään nimessä ei kannata pitää pisteitä pelaajien omissa kansioissa. Mielummin kaikki pisteet yhdessä tiedostossa. Tällöin pisteiden hakeminen on looginen kokonaisuus.
<?php $data = file("pisteet.txt"); $maara = count($data); $pisteet = Array(); for($i = 0; $i < $maara; $i++){ $osat = explode("|", $data[$i]); $nimi = trim($osat[0]); $piste = trim($osat[1]); $pisteet[$nimi] = $piste; } arsort($pisteet); foreach ($pisteet AS $key => $val) { echo "<li>$key = $val</li>"; }
Pisteet on formaatissa [nimi][piste] esim. Juha|15
Yritän tehdä taulukon tuolla for loopilla, nimi[pisteet]. Ei jaksa aina kehitellä erilaisia nimiä, mikä ensin tulee mieleen sillä mennään. Tiedän, huonoa ohjelmointia. Nimi pitääkin vaihtua joka kierroksella jotta saadaan kaikki nimet taulukkoon. Muutoin onnistuu, mutta tuo järjestäminen ontuu. En tiedä missä teen virheen, mutta tuolla neuvollasi ei onnistu. Muutin taulukon nimen toiseksi ja muutin hieman koodia, ei vaikutusta.
Tein sinun mallisi mukaisen, mutta toimivamman systeemin. Tässä on kieltämättä ultraselkeät muuttujien nimet, mutta ainakin selviää mitä niissä on :)
<?php /** Määritellään alkuarvot ja tallennuspaikat **/ $pelaajien_nimet = file("nimet.txt"); $pelaajien_lukumaara = count($pelaajien_nimet); $pelaajien_pisteet = Array(); /** Luetaan jokaiselle pelaajalle nimi ja nimen perusteella oikeat pisteet **/ for ($i = 0; $i < $pelaajien_lukumaara; ++$i) { /** Asetetaan jokaiselle pelaajalle nimi ja haetaan oikeat pisteet **/ $pelaajan_nimi = trim($pelaajien_nimet[$i]); /** Haetaan tämän pelaajan pisteet **/ $pelaajan_pisteet = file_get_contents($pelaajan_nimi . "/yhpisteet.txt"); /** Varmistetaan tulostuksella, että menee oikein **/ echo "<p>{$pelaajan_nimi} = {$pelaajan_pisteet}</p>"; /** Tallennetaan pelaajan nimi ja pisteet **/ $pelaajien_pisteet[$pelaajan_nimi] = $pelaajan_pisteet; } /** Ruma kokeilu **/ arsort($pelaajien_pisteet); var_dump($pelaajien_pisteet);
Edelleen kuitenkin jo muutaman kymmenen käyttäjän kanssa sinulla on hirveä määrä kansioita hallittavana. Tämä ei kuulosta kauhean mukavalta ylläpitämiseltä. Liputan edelleen tuon kaikki pisteet yhteen tiedostoon, josta niiden hakeminen on selvästi helpompaa. Helpompaa eritoten siksi, että jokaisen käyhttäjän pisteet on hellpo yhdistää oikeaan nimeen. Tässä hajautetussa mallissa tiedosto (ilman kommentteja) ei indikoi käyttäjää mitenkään.
Tämä ohjelma on jo vuosia vanha ja toiminut moitteettomasti. Koska tietokantaa ei ollut saatavilla silloisella palvemimella niin päädyin rakentamaan tuollaisen nimi/tiedostot tuohon ohjelmaan. Tuossa nimikansiossa on paljon muutakin tietoa käyttäjästä, joten sen takia ne oli eroteltava toisistaan. Nimi oli minusta loogisin valinta tuohon rakenteeseen. Tiedän että on parempiakin koodeja joilla nuo voisi toteuttaa. Minua ei kiinnosta ohjelmointi sen enempää kuin on tarve, joten vähän purkkaviritelmiä niistä tulee. Osanottajia kyseisiin veikkauksiin on tullut alle kymmenen henkilöä, joten ei kansioita pitäisi tulla hirveitä määriä. Tämänkin sorttausohjelman yritän toteuttaa käyttäjien pyynnöstä. No, täytyy sitten tehdä oma "purkkaviritelmä" tuohon jos kerran sitä ei saa muutoin sortattua. En ala muuttelemaan ohjelmaa, koska se on parastaikaa käytössä.
Esitän tässä vaihtoehtoisen tavan käyttäjätietojen hallintaan. Ensin laitetaan kaikki käyttäjät yhteen tiedostoon, jossa on käyttäjien perustiedot.
248|kievari|Kalle|Könkkölä|Sivukuja 13|kalle.konkkola@eduskunta.fi|sfdsdf454zf65ds34|Edustan sinuakin 8579|simpura|Pekka|Rautaneva|Seonkuja 7|seppo.koodaa@hienosti.com|rtegdfd|Helppoa
Sitten toiseen tiedostoon asetellaan pisteet id-numeron kanssa.
248|152 8579|15
Lopuksi yhdistetään nämä kaksi tiedostoa sopivalla koodilla yhteen.
<?php /** Määritellään alkuarvot ja tallennuspaikat **/ $pelaajien_tiedot = file("kayttajat.txt"); $pelaajien_lukumaara = count($pelaajien_tiedot); $pelaajien_pisteet = Array(); /** Pisteiden hakeminen id-numeron perusteella **/ function hae_pisteet($pelaajan_id) { /** Haetaan kaikki pisteet taulukkoon **/ $pisteet = file("pisteet.txt"); /** Käydään jokainen pisterivi läpi **/ for($i = 0; $i < count($pisteet); ++$i) { /** Ositellaan rivi erotusmerkin kohdalta **/ $purettu = explode("|", $pisteet[$i]); /** Verrataan kuuluvatko nämä pisteet tälle id-numerolle **/ if ($pelaajan_id == $purettu[0]) { /** Jos kuuluvat, niin palautetaan tämä pistemäärä kutsujalle **/ return $purettu[1]; } } /** Pelaajalle ei löytynyt pisteitä, joten pisteet on nolla **/ return 0; } /** Luetaan jokaiselle pelaajalle nimi ja nimen perusteella oikeat pisteet **/ for ($i = 0; $i < $pelaajien_lukumaara; ++$i) { /** Purtetaan pelaajien tiedot **/ $pelaajat_ositeltu = explode("|", $pelaajien_tiedot[$i]); /** Asetellaan pelaajan tiedot muuttujiin **/ list($pelaajan_id, $pelaajan_nimimerkki, $pelaajan_etunimi, $pelaajan_sukunimi, $pelaajan_osoite, $pelaajan_email, $pelaajan_tiiviste, $pelaajan_kuvaus) = $pelaajat_ositeltu; /** Haetaan tämän pelaajan pisteet **/ $pelaajan_pisteet = hae_pisteet($pelaajan_id); /** Tallennetaan pelaajan nimi ja pisteet **/ $pelaajien_pisteet[$pelaajan_nimimerkki] = $pelaajan_pisteet; } /** Järjestellään tulokset **/ arsort($pelaajien_pisteet); /** Tulostetaan tulokset esille **/ foreach ($pelaajien_pisteet AS $nimi => $piste) { echo "<li>{$nimi} = {$piste}</li>"; }
Nyt tietojen käsittely on helppoa ja muutoksia entiseen ei tarvitse tehä paljoa. Uuden käyttäjän lisääminen on myös helppoa, koska uusi vain lisätään entisten perään. Oikealla tietokannalla tämä olisi tietysti paljon yksinkertaisempaa ja toimintavarmempaa.
novari kirjoitti:
No, täytyy sitten tehdä oma "purkkaviritelmä" tuohon jos kerran sitä ei saa muutoin sortattua. En ala muuttelemaan ohjelmaa, koska se on parastaikaa käytössä.
Oliko tuossa edellisessä jokin ongelma, koska sen pitäisi toimia ihan suoraan ja oikein.
Aihe on jo aika vanha, joten et voi enää vastata siihen.