[PHP]Multi array sorteren

Pagina: 1
Acties:
  • 209 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • SinergyX
  • Registratie: November 2001
  • Laatst online: 18:12

SinergyX

____(>^^(>0o)>____

Topicstarter
Ik heb hier een brievenboek programma die nog regelmatig wordt gebruikt, als soort van 2de administratie. Nu zijn er andere mensen die toch wat inzicht willen hebben in uitgaande post, echter is dit een single user programma maar gelukkig wel met een XML export. Ik dacht een simpele PHP pagina die de informatie kon weergeven en wat kon sorteren.
De persoon die dit programma heeft geschreven (VB?) is al weer ruime tijd niet in dienst, dus aanpassing van evt output is niet mogelijk. Omdat dit enkel voor wat overzichten is, was het niet 'van belang' over te stappen op een ander programma.

Reeds heb ik via een script (xmlfiletoArray) het XML bestand kunnen omzetten tot een werkbaar array, in code vorm:

code:
1
2
3
4
5
$post = array(
   array('id' => 11, 'afzender' => 'herman', 'briefnummer' => 13),
   array('id' => 12, 'afzender' => 'piet', 'briefnummer' => 11),
   array('id' => 13, 'afzender' => 'kees', 'briefnummer' => 12)
);

Met een simpele for each laat ik de informatie in een tabel zien. Natuurlijk met meer informatie, maar even in grote lijnen. Het probleem zit dus in 'id', waar ook het XML bestand al was gesorteerd. Gezien post niet altijd chronologisch of op briefnummer is ingevoerd, loop ik tegen een probleem, ze willen dus ook kunnen sorteren op bv persoon, briefnummer of datum.

Nu ben ik een grote leek in arrays, gelukkig is php.net mijn vriend. Inmiddels zwaar aan het stoeien geweest met sort, asort, maar ik krijg deze array niet gesorteerd op bv briefnummer. Usort loop ik vast op het feit dat deze arrays los van elkaar staan en niet, zoals ik veel usort voorbeelden vind, gekoppeld. Als ik een Array_keys gebruik krijg ik enkele en 0=>0, 1=>1 etc.

Met de wanhoop naarbij, dacht ik dus nog aan 2 opties. De arrays volledig opnieuw opbouwen met makkelijk werkende arrays (id => 11,12,13 en briefnummer => 13,11,12) en deze via usort gaan sorteren, of alles maar in een mysql te zetten en daarmee aan de slag gaan, gezien ik daar stuk meer ervaring in heb. Nu blijft mijn vraag, is het met bovenstaande array mogelijk deze te sorteren op bv briefnummer?

Nog 1 keertje.. het is SinergyX, niet SynergyX
Im as excited to be here as a 42 gnome warlock who rolled on a green pair of cloth boots but was given a epic staff of uber awsome noob pwning by accident.


Acties:
  • 0 Henk 'm!

  • MacWebber
  • Registratie: September 2000
  • Niet online
Volgens mij zou usort() toch je vriend moeten zijn. Even zonder testen:

PHP:
1
2
3
4
5
6
7
8
<?php
function cmp($a, $b)
{
    return strcmp($a["briefnummer"], $b["briefnummer"]);
}

usort($post, "cmp");
?> 

Acties:
  • 0 Henk 'm!

  • SinergyX
  • Registratie: November 2001
  • Laatst online: 18:12

SinergyX

____(>^^(>0o)>____

Topicstarter
Moet ik toch beter opletten op mijn vrienden :$
Begrijp nu dat ik usort dus steeds verkeerd begreep en codeer.
Alleen strcmp herkent 21 lager als 3, maar die oplossing heb ik van php.net kunnen vinden :)
code:
1
2
3
4
5
    if ($a == $b) {
        return 0;
    }
    return ($a < $b) ? -1 : 1;
}


In neem aan dat ik strcmp wel kan gebruiken bij namen? (alfabetisch)

Nog 1 keertje.. het is SinergyX, niet SynergyX
Im as excited to be here as a 42 gnome warlock who rolled on a green pair of cloth boots but was given a epic staff of uber awsome noob pwning by accident.


Acties:
  • 0 Henk 'm!

  • robbert
  • Registratie: April 2002
  • Laatst online: 11:40
Je kan er ook een mooie onliner van maken :)

PHP:
1
usort($post, create_function('$a, $b', '$k="briefnummer"; return $a[$k] == $b[$k] ? 0 : ($a[$k] < $b[$k] ? -1 : 1);'));

[ Voor 1% gewijzigd door robbert op 26-11-2007 21:14 . Reden: typo gefixed ]


Acties:
  • 0 Henk 'm!

  • MacWebber
  • Registratie: September 2000
  • Niet online
Ja, uiteraard. Had ik even overheen gekeken. Strcmp is uiteraard alleen handig voor strings.

Acties:
  • 0 Henk 'm!

  • blackangel
  • Registratie: April 2002
  • Laatst online: 18-09 12:58
robbert schreef op maandag 26 november 2007 @ 20:44:
Je kan er ook een mooie onliner van maken :)

PHP:
1
usort($post, create_function('$a, $b', '$k="briefnummer"; return $a[$k] == $b[$k] ? true : ($a[$k] < $b[$k] ? -1 : 1);'));
volgens mij moet
code:
1
return $a[$k] == $b[$k] ? true : ...
niet true zijn, maar false? false is 0, wat bij usort geldt als gelijk (zelfde als strcmp dus). true daarintegen is alles behalve 0, dus alles behalve gelijk.

Het kan best aan mij liggen dat ik het fout heb overigens hoor, maar ik ben wel nieuwsgierig of php zoveel anders (wil zijn dan) de meeste andere talen of dat het gewoon een foutje is :)

Acties:
  • 0 Henk 'm!

  • robbert
  • Registratie: April 2002
  • Laatst online: 11:40
blackangel schreef op maandag 26 november 2007 @ 21:08:
[...]


volgens mij moet
code:
1
return $a[$k] == $b[$k] ? true : ...
niet true zijn, maar false? false is 0, wat bij usort geldt als gelijk (zelfde als strcmp dus). true daarintegen is alles behalve 0, dus alles behalve gelijk.

Het kan best aan mij liggen dat ik het fout heb overigens hoor, maar ik ben wel nieuwsgierig of php zoveel anders (wil zijn dan) de meeste andere talen of dat het gewoon een foutje is :)
Typo inderdaad :)

Acties:
  • 0 Henk 'm!

Verwijderd

Of je gebruikt strnatcmp (http://www.php.net/manual/en/function.strnatcmp.php) als je per se strings wil vergelijken. Maar als het altijd integers zijn, zal een integer comparison wel sneller zijn dan een string comparison denk ik zo...

Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Nu online

crisp

Devver

Pixelated

Voor getallen kan je gewoon dit als compare functie gebruiken:
PHP:
1
2
3
4
5
6
function cmp($a, $b)
{
    return $a['index'] - $b['index'];
}

usort($array, 'cmp');

alternatief is het gebruik van array_multisort (meestal ook sneller):
PHP:
1
2
3
4
$sortfields = array();
foreach ($array as $item)
    $sortfields[] = $item['index'];
array_multisort($sortfields, SORT_NUMERIC, SORT_ASC, $array);

Intentionally left blank

Pagina: 1