[PHP] Array sorteren op voorkomen

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

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Geachte lezer,

Ik heb een array met daarin een aantal waarden. Een paar van deze waarden zullen gelijk zijn, en deze wil ik graag sorteren.

Nu weet ik dat er talloze sorteerfuncties zijn voor Array's, maar dat geeft nog niet de uitkomst waar ik op doel.

Het is namelijk de bedoeling dat de meest voorkomende waarden vooraan de array komen te staan.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Array test (
[0] => "Test Q",
[1] => "Test X",
[2] => "Test Q",
[3] => "Test A",
[4] => "Test X",
[5] => "Test Q")

Moet worden:

Array test (
[0] => "Test Q",
[1] => "Test Q",
[2] => "Test Q",
[3] => "Test X",
[4] => "Test X",
[5] => "Test A")


Heeft iemand enig idee hoe ik dit oplos?

Acties:
  • 0 Henk 'm!

  • SchizoDuckie
  • Registratie: April 2001
  • Laatst online: 18-02 23:12

SchizoDuckie

Kwaak

ik vrees dat je er niet aan komt om een custom array_walk functie te nemen in dit geval met een custom sort functie.

Verder horen PHP topics uiteraard in /14 ;)

Stop uploading passwords to Github!


Acties:
  • 0 Henk 'm!

  • Icelus
  • Registratie: Januari 2004
  • Niet online
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
function mySort($a)
{
   $GLOBALS['__mySort__'] = array_count_values( $a );
   
   function __mySort($a,$b)
   {
      return $GLOBALS['__mySort__'][ $b ] - $GLOBALS['__mySort__'][ $a ];
   }
   
   usort( $a, '__mySort' );
   unset( $GLOBALS['__mySort__'] );
   return $a;
}

Developer Accused Of Unreadable Code Refuses To Comment


Acties:
  • 0 Henk 'm!

  • P.O. Box
  • Registratie: Augustus 2005
  • Niet online

Acties:
  • 0 Henk 'm!

Verwijderd

volgens mij kan je daar het beste array_unique voor gebruiken:

http://nl3.php.net/array_unique

Bij de comments staat nog een functie die ook telt hoe vaak een waarde voorkomt, op basis daarvan moet dit wel te doen zijn.

Acties:
  • 0 Henk 'm!

  • robbert
  • Registratie: April 2002
  • Laatst online: 20:37
Zoiets misschien
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
$array = Array (
0 => "Test Q",
1 => "Test X",
2 => "Test Q",
3 => "Test A",
4 => "Test X",
5 => "Test Q");

$result = array();
$aantallen = array_count_values($array);
foreach(array_unique($array) as $elem)
    $result = array_merge($result, array_fill(0, $aantallen[$elem], $elem));


Ik heb overigens geen idee of het enigszins efficiënt is.

Acties:
  • 0 Henk 'm!

  • GlowMouse
  • Registratie: November 2002
  • Niet online
Robberts methode gaat fout wanneer je in zijn array de eerste X en A omwisselt.

Acties:
  • 0 Henk 'm!

  • robbert
  • Registratie: April 2002
  • Laatst online: 20:37
GlowMouse schreef op vrijdag 06 juli 2007 @ 12:26:
Robberts methode gaat fout wanneer je in zijn array de eerste X en A omwisselt.
Bedoel je het volgende:
PHP:
1
2
3
4
5
6
7
$array = Array (
0 => "Test Q",
1 => "Test A",
2 => "Test Q",
3 => "Test X",
4 => "Test X",
5 => "Test Q");

Dit toch het goede resultaat:
PHP:
1
2
3
4
5
6
7
8
9
Array
(
    [0] => Test Q
    [1] => Test Q
    [2] => Test Q
    [3] => Test A
    [4] => Test X
    [5] => Test X
)

Of niet?

Acties:
  • 0 Henk 'm!

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 22-07-2024
robbert schreef op vrijdag 06 juli 2007 @ 12:33:
Dit toch het goede resultaat? Of niet?
nee want X komt vaker voor dan A en zou dus boven A moeten staan

[ Voor 42% gewijzigd door BasieP op 06-07-2007 12:36 ]

This message was sent on 100% recyclable electrons.


Acties:
  • 0 Henk 'm!

  • BtM909
  • Registratie: Juni 2000
  • Niet online

BtM909

Watch out Guys...

Ace of Base vs Charli XCX - All That She Boom Claps (RMT) | Clean Bandit vs Galantis - I'd Rather Be You (RMT)
You've moved up on my notch-list. You have 1 notch
I have a black belt in Kung Flu.


Acties:
  • 0 Henk 'm!

  • robbert
  • Registratie: April 2002
  • Laatst online: 20:37
BasieP schreef op vrijdag 06 juli 2007 @ 12:35:
[...]

nee want X komt vaker voor dan A en zou dus boven A moeten staan
Ik zat nog te slapen, ik dacht "sorteren op eerste voorkomen" ipv op "meest voorkomen". :)

Acties:
  • 0 Henk 'm!

  • Tead
  • Registratie: November 2001
  • Laatst online: 17-09 10:14

Tead

nnb

Deze zal moeten werken.

Succes er mee!

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function sort_count_array($array){
    $array2 = array();
    $return = array();
    foreach(array_unique($array) as $item)
        $array2[$item] = count(array_keys($array, $item));
    arsort($array2);
    
    foreach($array2 as $key => $item){
        for($i=0;$i<$item;$i++){
             array_push($return, $key);
        }
    }
    return $return;
}

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Mijn dank is groot...werkt als een trein!

Acties:
  • 0 Henk 'm!

Verwijderd

offtopic:
Ik ben erg tegen dergelijke posts. Het heeft een hoog 'kijk eens hoe goed ik kan programmeren' gehalte, en het helpt daadwerkelijk niemand (ook niet TS maar dat zal hij/zij vast niet beamen).

Al die kant en klaar oplossingen zorgen er enkel voor dat script requests toenemen. Je leert er tevens nauwelijks iets van: De TS niet omdat die niet over het probleem moet nadenken, en jij zelf ook niet omdat je niet nadenkt over hoe je abstracte concepten aan anderen duidelijk kunt maken.

Zo dat vind ik er van :)

Acties:
  • 0 Henk 'm!

  • Gonadan
  • Registratie: Februari 2004
  • Nu online

Gonadan

Admin Beeld & Geluid, Harde Waren
Deze vind ik makkelijker, is ook eigenlijk de bedoeling.
Je wilt een sortering op basis van een eigen vergelijking. Dan hoor je usort te gebruiken.
De oplossing hierboven doet wel hetzelfde maar dan ben je eigenlijk het wiel opnieuw aan het uitvinden. :)

PHP:
1
2
3
4
5
6
7
8
9
$vcount = array_count_values($array);

function count_sort($a, $b) {
  global $vcount;
  if ($vcount[$a] == $vcount[$b]) return 0;
  return ($vcount[$a] > $vcount[$b]) ? 1 : -1;
}

usort ($array, "count_sort");


Niet getest trouwens. ;)

[ Voor 28% gewijzigd door Gonadan op 06-07-2007 13:50 ]

Look for the signal in your life, not the noise.

Canon R6 | 50 f/1.8 STM | 430EX II
Sigma 85 f/1.4 Art | 100-400 Contemporary
Zeiss Distagon 21 f/2.8


Acties:
  • 0 Henk 'm!

  • Tead
  • Registratie: November 2001
  • Laatst online: 17-09 10:14

Tead

nnb

Verwijderd schreef op vrijdag 06 juli 2007 @ 13:40:
[...]
offtopic:
Ik ben erg tegen dergelijke posts. Het heeft een hoog 'kijk eens hoe goed ik kan programmeren' gehalte, en het helpt daadwerkelijk niemand (ook niet TS maar dat zal hij/zij vast niet beamen).

Al die kant en klaar oplossingen zorgen er enkel voor dat script requests toenemen. Je leert er tevens nauwelijks iets van: De TS niet omdat die niet over het probleem moet nadenken, en jij zelf ook niet omdat je niet nadenkt over hoe je abstracte concepten aan anderen duidelijk kunt maken.

Zo dat vind ik er van :)
Wat een onzin. Stukjes code lezen kan je heel veel van leren. Deze functie had ik ooit al eens gemaakt en had ik klaar liggen. TS is geholpen met zijn probleem en kan deze code lezen en proberen te begrijpen wat zijn inzicht weer vergroot.

Verder vind ik dit niet een mooi voorbeeld van 'kijk eens hoe goed ik kan programmeren'. De functie die Icelus had geschreven zit veel degelijker in elkaar en gebruikt de functie "usort" waarvoor deze bedoeld is.

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

Ik vraag me af waarvoor de topicstarter dit nodig heeft. Ik heb namelijk het idee dat een frequentie tabelletje maken waarschijnlijk een stuk efficiënter zal zijn.

@Tead: De naive gedachte dat mensen aangereikte code gaan bestuderen voordat ze het in hun project copy pasten heb ik helaas jaren terug al moeten laten varen.

[ Voor 33% gewijzigd door Janoz op 06-07-2007 14:00 ]

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Gonadan
  • Registratie: Februari 2004
  • Nu online

Gonadan

Admin Beeld & Geluid, Harde Waren
Tead schreef op vrijdag 06 juli 2007 @ 13:57:
Wat een onzin. Stukjes code lezen kan je heel veel van leren. Deze functie had ik ooit al eens gemaakt en had ik klaar liggen. TS is geholpen met zijn probleem en kan deze code lezen en proberen te begrijpen wat zijn inzicht weer vergroot.
Zeker geen onzin, alleen niet al te subtiel gebracht misshien. ;)
Dat je de code al had liggen en dat je de TS wilt helpen is natuurlijk prima.
Maar je weet ook dat veel mensen de code die ze krijgen niet gaan uitpluizen en proberen te snappen maar klakkeloos knippen en plakken waardoor ze bij een volgend probleem weer een topic moeten maken.
En dat is nou net wat tweakers niet wil ;)

Ik zeg niet dat het in dit geval zo is, maar het gebeurt wel vaak.
Verder vind ik dit niet een mooi voorbeeld van 'kijk eens hoe goed ik kan programmeren'. De functie die Icelus had geschreven zit veel degelijker in elkaar en gebruikt de functie "usort" waarvoor deze bedoeld is.
*leest functie van Icelus*
Lekker, volgende keer dus beter lezen. :+

Look for the signal in your life, not the noise.

Canon R6 | 50 f/1.8 STM | 430EX II
Sigma 85 f/1.4 Art | 100-400 Contemporary
Zeiss Distagon 21 f/2.8


Acties:
  • 0 Henk 'm!

  • robbert
  • Registratie: April 2002
  • Laatst online: 20:37
Janoz schreef op vrijdag 06 juli 2007 @ 13:58:
@Tead: De naive gedachte dat mensen aangereikte code gaan bestuderen voordat ze het in hun project copy pasten heb ik helaas jaren terug al moeten laten varen.
Dit soort stukjes code zou ik zeker niet zonder ze zelf te bestuderen in mijn project plaatsen. Ik wil zelf eerst wel eens begrijpen waarom het werkt, anders heb ik een probleem als ik er ooit iets aan moet veranderen. Maar hier ben ik blijkbaar een uitzondering in. :)

Als ik een of andere library gebruik ga ik ik die niet natuurlijk niet op code niveau bestuderen, enkel hoe ik het ding moet gebruiken.

Acties:
  • 0 Henk 'm!

  • Tead
  • Registratie: November 2001
  • Laatst online: 17-09 10:14

Tead

nnb

Janoz schreef op vrijdag 06 juli 2007 @ 13:58:
@Tead: De naive gedachte dat mensen aangereikte code gaan bestuderen voordat ze het in hun project copy pasten heb ik helaas jaren terug al moeten laten varen.
Een politiek correcte reactie op zo'n soort topic zou dus moeten zijn:

"kijk eens naar usort()" 8)

Acties:
  • 0 Henk 'm!

  • P.O. Box
  • Registratie: Augustus 2005
  • Niet online
ahum, en mijn code werkte niet?

Acties:
  • 0 Henk 'm!

  • Gonadan
  • Registratie: Februari 2004
  • Nu online

Gonadan

Admin Beeld & Geluid, Harde Waren
Edwardvb schreef op vrijdag 06 juli 2007 @ 14:09:
ahum, en mijn code werkte niet?
Jouw code lijkt verdacht veel op een alias van array_unique() ;)

Look for the signal in your life, not the noise.

Canon R6 | 50 f/1.8 STM | 430EX II
Sigma 85 f/1.4 Art | 100-400 Contemporary
Zeiss Distagon 21 f/2.8


Acties:
  • 0 Henk 'm!

  • Tead
  • Registratie: November 2001
  • Laatst online: 17-09 10:14

Tead

nnb

Edwardvb schreef op vrijdag 06 juli 2007 @ 14:09:
ahum, en mijn code werkte niet?
Nee, deze drukt alleen alle unieke items. Dus:
code:
1
2
3
4
[0] => "Test Q"
[1] => "Test A"
[2] => "Test X"
[3] => "Test Y"

Acties:
  • 0 Henk 'm!

  • SchizoDuckie
  • Registratie: April 2001
  • Laatst online: 18-02 23:12

SchizoDuckie

Kwaak

Ik heb, lezende het topique zomaar hetidee dat deze data ook uit een sql query komt nog...

en als deze array dan uit een SQL query komt is het dan niet een goed idee om een order by count(item) mee te nemen in je query? dan ben je er meteen namelijk :P

Stop uploading passwords to Github!


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

Tead schreef op vrijdag 06 juli 2007 @ 14:09:
[...]

Een politiek correcte reactie op zo'n soort topic zou dus moeten zijn:

"kijk eens naar usort()" 8)
Wat ik zelf vaak doe is een voorbeeldje in psuedo code uit te schrijven. Op die manier is het koren erg makkelijk van het kaf te scheiden.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

Verwijderd

Tead schreef op vrijdag 06 juli 2007 @ 14:09:
Een politiek correcte reactie op zo'n soort topic zou dus moeten zijn:

"kijk eens naar usort()" 8)
Niet politiek correct, maar echt behulpzaam. Dus ook voor de lange termijn. Je kunt iemand ook de juiste richting opduwen en zelf laten nadenken om tot het juiste resultaat te komen. Zoals janoz al aangeeft is pseudo code daar een hele goede in. Programmeren is meer dan alleen code invoeren, het is ook nadenken over een probleem. :)

Acties:
  • 0 Henk 'm!

  • Gonadan
  • Registratie: Februari 2004
  • Nu online

Gonadan

Admin Beeld & Geluid, Harde Waren
Geef dan eens een voorbeeld van hoe je deze vraag in pseudocode zou beantwoorden?
Ben ik wel benieuwd naar. :)

Look for the signal in your life, not the noise.

Canon R6 | 50 f/1.8 STM | 430EX II
Sigma 85 f/1.4 Art | 100-400 Contemporary
Zeiss Distagon 21 f/2.8


Acties:
  • 0 Henk 'm!

  • P.O. Box
  • Registratie: Augustus 2005
  • Niet online
Tead schreef op vrijdag 06 juli 2007 @ 14:13:
[...]

Nee, deze drukt alleen alle unieke items. Dus:
code:
1
2
3
4
[0] => "Test Q"
[1] => "Test A"
[2] => "Test X"
[3] => "Test Y"
och, natuurlijk... dom van me....

tsja, dan zal het toch iets uitgebreider moeten... ook niet al te ingewikkeld natuurlijk...
deze oplossing heb ik dan nog niet gezien:
code:
1
2
3
4
5
initialiseer resultaatarray;
$aCount = aantal voorkomens van iedere waarde in $array;
voor ieder element uit $aCount {
    voeg $aCount[element] aantal keer "element" toe aan resultaat-array
}

[ Voor 3% gewijzigd door P.O. Box op 06-07-2007 14:39 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Gonadan schreef op vrijdag 06 juli 2007 @ 14:30:
Geef dan eens een voorbeeld van hoe je deze vraag in pseudocode zou beantwoorden?
Ben ik wel benieuwd naar. :)
Prima, ik ben overigens niet op de hoogte van de php library, dus dat kunnen jullie vast beter.
We hebben bijvoorbeeld een map met key-value paren waarin we gaan bijhouden hoe vaak een bepaald element voorkomt en dan krijgen we iets zoals dit. Dus de key is het element en de value is een getal(count)
code:
1
2
3
4
5
6
7
foreach elementen als element
    if element in element map
       verhoog element count in map
    else
       voeg element toe aan map met count 1
    end if-else
end foreach

Acties:
  • 0 Henk 'm!

  • glashio
  • Registratie: Oktober 2001
  • Laatst online: 18-09 10:13

glashio

C64 > AMIGA > PC

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?php
$array = Array(
    Array('Test Q'),
    'Test X',
    'Test Q',
    'Test A',
    'Test X',
    'Test X',
    new stdClass(),
    array('Test Q'),
    'Test X',
    array('Test Q'),
    'Test Q',
    new stdClass(),
);

function &osort($arr) {
    $vals = array_unique($arr);
    $cnts = $ret = array();
    foreach(array_keys($vals) as $ix)
        $cnts[$ix] = count(array_keys($arr, $vals[$ix]));
    arsort($cnts, SORT_NUMERIC);
    foreach($cnts as $ix => $cnt)
        array_push($ret, array_fill(0, $cnt, $vals[$ix]));
    return $ret;
}

print_r(osort($array));
?>


Om deze functie generiek te houden voor alle type variabelen in de array zou dit een oplossing zijn :)

> Google Certified Searcher
> Make users so committed to Google that it would be painful to leave
> C64 Gospel
> [SjoQ] = SjoQing


Acties:
  • 0 Henk 'm!

  • koekiemonster
  • Registratie: Maart 2001
  • Laatst online: 13-08 19:58

koekiemonster

want a cookie

SchizoDuckie schreef op vrijdag 06 juli 2007 @ 14:19:
Ik heb, lezende het topique zomaar hetidee dat deze data ook uit een sql query komt nog...

en als deze array dan uit een SQL query komt is het dan niet een goed idee om een order by count(item) mee te nemen in je query? dan ben je er meteen namelijk :P
exact, dit is het eerste wat in me opkwam.

[webhero.nl]

Pagina: 1