Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien
Toon posts:

[PHP] Array sorteren op custom volgorde (usort?)

Pagina: 1
Acties:

Onderwerpen


Verwijderd

Topicstarter
Hallo allemaal, ik probeer nu al 3 dagen een array te sorteren maar kom er niet mee verder.
De array ziet er als volgt uit:

b,b1,b2,b3,b4,b5,b6,b7,b8,b9,
t1,t2,t3,t4,t5,t6,t7,t8,t9,
k1,k2,k3,k4,k5,k6,k7,k8,k9,
dr,dg,dw,ww,wn,wo,wz

Nu probeer ik deze array te sorteren in deze volgorde:

b1 tot en met b9
k1 tot en met k9
t1 tot en met t9
alles met een w als eerste letter
alles met een d als eerste letter
b (want de letter b hoort niet in de rij met b1 tot en met b9 thuis)

De code die ik nu heb ziet er als volgt uit (maar werkt dus niet, en heb ik al vele malen aangepast om van alles te proberen):

code:
1
2
3
4
5
6
7
8
9
10
11
    $sc = array_diff( scandir('../img'), array('.', '..') );
    function sort_func($search) {
        $so = array('b','k','t','w','d');
        $position = array_search($search, $so);
        return $position != false ? $position : $position++;
    }
    function sorteren($a, $b) {
        return sort_func($a[0]) < sort_func($b[0]) ? -1 : 0;
    }
    usort($sc, 'sorteren');
    print_r($sc);


Nu heb ik hier op het forum nog meer topics gezien over dit onderwerp maar die zijn niet zo specifiek qua sorteren voor zover ik heb gezien. Ik hoop dat iemand de oplossing weet voor die probleem want ik kom er echt niet meer uit... iets met bomen en een bos meen ik.

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Hebben we het hier over een enkel-dimensionale array of een multidimensionale array want dat wordt me niet duidelijk uit je startpost.

Heb je dus:
PHP:
1
2
3
4
5
6
7
$a = array('b','b1','b2',...,'t1','t2',...);
//of
$a = array(
  array('b','b1','b2',...),
  array('t1','t2','t2',...),
  ...
);

?

En heb je al gedebugged (Debuggen: Hoe doe ik dat?)? En wat kwam daar uit?

[ Voor 20% gewijzigd door RobIII op 16-01-2012 13:00 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • mithras
  • Registratie: Maart 2003
  • Niet online
Als je je eisen reduceert tot een wat abstractere versie, kom je eigenlijk uit op dit:

[ol]
• Is het item 1 karakter lang (de 'b') zorg dan dat deze altijd achteraan komt
• Zo nee, maar zijn beide eerste karakters gelijk, kijk dan naar het tweede karakter
• Zo nee, sorteer dan op basis van het eerste karakter vanuit een voorgedefinieerde lijst


Komt neer op (geef ik gelijk het antwoord :N ):
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$list = array('b','b1','b2','b3','b4','b5','b6','b7','b8','b9',
't1','t2','t3','t4','t5','t6','t7','t8','t9',
'k1','k2','k3','k4','k5','k6','k7','k8','k9',
'dr','dg','dw','ww','wn','wo','wz');

usort($list, function($a, $b) {
  if (1 === strlen($a) || 1 === strlen($b)) {
    return strlen($a) > strlen($b) ? -1 : 1;
  }

  if ($a[0] === $b[0]) {
    return $a[1] > $b[1] ? 1 : -1;
  }

  $order = array('b', 'k', 't', 'w', 'd');
  return array_search($a[0], $order) > array_search($b[0], $order) ? 1 : -1;
});

Verwijderd

Topicstarter
RobIII schreef op maandag 16 januari 2012 @ 12:58:
Hebben we het hier over een enkel-dimensionale array of een multidimensionale array want dat wordt me niet duidelijk uit je startpost.

Heb je dus:
PHP:
1
2
3
4
5
6
7
$a = array('b','b1','b2',...,'t1','t2',...);
//of
$a = array(
  array('b','b1','b2',...),
  array('t1','t2','t2',...),
  ...
);

?

En heb je al gedebugged (Debuggen: Hoe doe ik dat?)? En wat kwam daar uit?
Nee het eerste, het is 1 array die in 1 keer wordt gebouwd uit de directory inhoud. Enkel-dimensionaal dus als ik het goed begrijp.

@mithras:
Ik krijg met deze code Parse error: syntax error, unexpected T_FUNCTION op regel 14 retour.
Dat is deze regel: usort($sc, function($a, $b) {

Maar ik zie wel uit jouw code hoe jij het benaderd idd, wellicht dat ik er verder mee kom! ik ben helaas geen expert hierin maar ik denk wel dat ik er goed mee geholpen ben! Zo niet kom ik zeker weer terug om nog een vervolg vraag te stellen.

Super bedankt beide!

Extra edit: oh verdikkeme, heeft dat niet te maken met php 5.3? dat het dan pas zou moeten werken... mijn hosting provider upgrade pas komende maand naar 5.3.... als ik het nu op de oudewetse manier doe blijft het dan wel werken in 5.3? (neem aan van wel?)

[ Voor 52% gewijzigd door Verwijderd op 16-01-2012 13:51 ]


  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Verwijderd schreef op maandag 16 januari 2012 @ 13:41:
Nee het eerste, het is 1 array die in 1 keer wordt gebouwd uit de directory inhoud. Enkel-dimensionaal dus als ik het goed begrijp.
Ja, ik zag 't later toen ik eens goed naar je code keek :P
Heb je je probleem al eens geprobeerd in 'hapklare brokjes' op te splitsen, dat in pseudo-code om te zetten en 't vervolgens in code omgezet?

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Verwijderd

Topicstarter
Ohja nog antwoord op je vraag over het debuggen: ja dat doe ik meestal door gewoon door alles te printen waarmee ik werkt, zoals de array, de uitkomst van een if/else statement etc.. zodat ik zelf kan zien of dat wel goed gaat. Dus ja ik heb wel enigzins gedebugd maar ik ben absoluut een beginner met PHP.

Code opsplitsen & pseudo-code zegt mij eigenlijk niets, opsplitsen kan ik me bij voorstellen dat ik stukje voor stukje de code schrijf en de output laat zien, dan pas de volgende bewerking uitvoer? (zo werk ik standaard, en uiteindelijk voeg ik dan alles samen in een zo compact mogelijke code)

Bedoel je dat?

Edit:
Ik heb idd nu de code van mithras op de ouderwetse manier gemaakt door eerst de functie te bouwen en daarnaar te verwijzen in de usort functie. Dit werkt!
Nu is alleen nog niet de waarde 'b' helemaal op het einde maar aan het begin, dus nog voor b1,b2,etc.
Maar dit kan ik wellicht zelf nog oplossen.

Ik ben echt heel erg blij dat dit nu eindelijk werkt, en nog mooier/korter dan de code die ik al had, super hulp.

[ Voor 25% gewijzigd door Verwijderd op 16-01-2012 13:59 ]


  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Verwijderd schreef op maandag 16 januari 2012 @ 13:55:
Code opsplitsen & pseudo-code zegt mij eigenlijk niets, opsplitsen kan ik me bij voorstellen dat ik stukje voor stukje de code schrijf en de output laat zien, dan pas de volgende bewerking uitvoer? (zo werk ik standaard, en uiteindelijk voeg ik dan alles samen in een zo compact mogelijke code)
Wat ik daarmee bedoel is je (deel)probleem opdelen in kleine(re) (deel)problemen om zo de zaak overzichtelijk te krijgen. Niemand ontwerpt een Boeing 747, maar er is wel (bijvoorbeeld) 1 afdeling die een staartstuk ontwerpt, en daar werkt weer iemand die zich bezig houdt met 't motortje dat het roer laat bewegen. Als je dan later alle onderdelen samenvoegt heb je een Boeing... euh, oplossing voor je probleem ;)

[ Voor 8% gewijzigd door RobIII op 16-01-2012 14:04 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Verwijderd

Topicstarter
Ja dat bedoelde ik ook RobIII, zo werk ik normaliter dus altijd omdat ik een beginner ben met PHP. Op deze wijze had ik dit stukje code voorheen maar ben het nu al een week aan het omzetten naar een overzichtelijkere en professionelere code, totdat ik er ineens niet meer uit kwam bij het sorteren. Al het andere werk was me wel gelukt (met veel google werk natuurlijk, maar toch... het is gelukt).

Het resultaat mag er voorlopig zeker zijn, mijn eerste eigen plugin voor WordPress :)

Edit:
Volgens mij heb ik door waarom waarde 'b' niet achteraan komt te staan. Dit is ook mijn fout... de array wordt nu nog gevuld met de volledige bestandbenaming. Dus niet 'b' maar 'b.png' en dan is de strlen natuurlijk geen 1 maar 5 en anders altijd 6. Nu werkt dat ook gelukkig!

@mithras: je code is echt perfect, dat heb je ongelooflijk snel gedaan zeg... ik was er al bijna 3 dagen mee aan het stoeien....

[ Voor 30% gewijzigd door Verwijderd op 16-01-2012 14:32 ]

Pagina: 1