Avatar billede flushout Nybegynder
08. december 2004 - 15:56 Der er 6 kommentarer og
1 løsning

Sortering af array m. usort skal sortere string float, int

Hejsa

Jeg har lavet denne lille funktion til sortering af et multidimensionelt array. I mit array er der værdier af typen float, int og string. Sammenligningen vil altid være mellem to værdier af samme type.

Lig nu bruger jeg 'strcasecmp' til at foretage sammenligningen. Den virker også i 905 af tilfældene men en gang i mellem ser det ud som om den ikke kan sortere int ordentligt.

Er der nogen der kender en erstatning for 'strcasecmp' som kan sammenligne både strings med strings, float med floats og int med int eller er der en anden, og smartere måde at gøre det på.

-------------------------------

- $arr er typisk et array som dette:

Array (
    [0] => Array
        (
            [forhandler] => 20060
            [gennemsnit] => 801.83
            [spejlVenstre] => nej
        )
    [1] => Array
        (
            [forhandler] => 8656
            [gennemsnit] => 2000
            [spejlVenstre] => ja
        )
)

- $key er i dette tilfælde enten 'forhandler', 'gennemsnit' eller 'spejlVenstre'.

$order er 1 eller 0. $order bruges til sortering af arrayet efter en given rækkefølge.

----------------------

Her er min funktion:

// Returnerer et sorteret multidimensionelt array ’$arr’ efter den valgte ’$key’
function multiSort($arr,$key,$order){
    if ($order == 1){
        $compare = create_function('$a,$b','return strcasecmp($a["'.$key.'"],$b["'.$key.'"]);');
    }
    else {
        $compare = create_function('$a,$b','return strcasecmp($b["'.$key.'"],$a["'.$key.'"]);');
  }
  usort($arr,$compare);
  return $arr;
}
-------------------

På forhand tusind tak for hjælpen =)
Avatar billede jakoba Nybegynder
08. december 2004 - 16:13 #1
strenge sammenlignes fra venstre, tal sammenlignes på numerisk værdi.
når du sammenligner strenge er "ABC" mindre end "C"
når du sammenligner tal er 9 mindre end 1000
mend strengen "1000" er stadig mindre end strengen "9"

// Returnerer et sorteret multidimensionelt array ’$arr’ efter den valgte ’$key’
function multiSort($arr,$key,$order){
    if ($order == 1){
        if ( $key == 0 || $key == 1 ) { // sammenlign tal
            $compare = create_function('$a,$b','return 1*$a["'.$key.'"]-1*$b["'.$key.'"];');
        } else {                        // sammenlign strenge
            $compare = create_function('$a,$b','return strcasecmp($a["'.$key.'"],$b["'.$key.'"]);');
        }
    }
    else {
        if ( $key == 0 || $key == 1 ) { // sammenlign tal
            $compare = create_function('$a,$b','return 1*$b["'.$key.'"]-1*$a["'.$key.'"];');
        } else {                        // sammenlign strenge
            $compare = create_function('$a,$b','return strcasecmp($b["'.$key.'"],$a["'.$key.'"]);');
        }
  }
  usort($arr,$compare);
  return $arr;
}
Avatar billede coderdk Praktikant
08. december 2004 - 16:18 #2
Jeg ville lave det sådan:

<?php

    $arr = array();
    $arr[] = array(
            'forhandler' => 20060
            ,'gennemsnit' => 801.83
            ,'spejlVenstre' => 'nej'
        );
    $arr[] = array(
            'forhandler' => 8656
            ,'gennemsnit' => 2000
            ,'spejlVenstre' => 'ja'
        );

    function mysort( $a, $b )
    {
        global $sortby;
        global $stigende;
        if ( $a[$sortby] == $b[$sortby] )
        {
            return 0;
        }
        return ( ( $a[$sortby] < $b[$sortby] ? -1 : 1 ) * ( $stigende ? 1 : -1 ) );
    }

    echo "<b>Før</b><pre>"; var_dump( $arr ); echo "</pre>";
   
    $sortby = 'gennemsnit';
    $stigende = 1;
    usort( $arr, "mysort" );

    echo "<b>Efter</b><pre>"; var_dump( $arr ); echo "</pre>";

?>

Men jeg er også underlig :)
Avatar billede jakoba Nybegynder
08. december 2004 - 16:26 #3
Nae, det ville jeg også (fra scratch), men prøver at beholde mest mulig af spørgers logik :-))
Avatar billede coderdk Praktikant
08. december 2004 - 16:29 #4
jakoba, Ja, det kan der være en vis logik i :)
Avatar billede flushout Nybegynder
09. december 2004 - 09:11 #5
CoderDk din løsning virker umiddelbart fornuftig, men jeg foretrækker jakoba's, da den har det hele samlet i en funktion der hedder multisort (jeg kalder den ca. 100 steder i min kode og gider ikke rette det til :P)

Jakoba, den virker på det aray jeg viste herover, jeg bliver dog nød til at lave den mere generel, da det array jeg viste Jer er typisk men ikke den eneste type.. nogle gange er det kun strings, andre gange blandet andre gange kun floats..

Dvs jeg skal have ændret:

if ( $key == 0 || $key == 1 )

til noget i stil med:

  if (is_numeric($arr[$key]))

Men det havde jeg ikke succes med =/ Hvordan gør jeg det smartest?
Avatar billede flushout Nybegynder
09. december 2004 - 09:35 #6
hovsa... det er da også forkert..

if (is_numeric($arr[0][$key]))

virker :) ...

Tak til Jer begge for svar, jeg bruger Jakoba's løsning så Jakoba, smid et svar så får du points..
Avatar billede jakoba Nybegynder
09. december 2004 - 10:05 #7
takker
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester