webForumDet fria alternativet

Sortera en array - siffror blir fel

9 svar · 758 visningar · startad av learn

learnMedlem sedan jan. 20051 130 inlägg
#1

Jag sorterar en flerdimensionell array på följande sätt (usort) :

function sortera_array($a, $b) {

	global $ordning;

	return strcmp($a[$ordning], $b[$ordning]);
	
}

usort($min_array, "sortera_array");

Funkar bra på strängar/bokstäver men innehåller arrayen siffror blir det knas.

Exempel:

111
1192
128
162
346
36
444
454

Verkar som att funktionen inte hanterar dessa värden som siffror utan som strängar.

Hur gör jag? Jag har testat köra intval() på det som stoppas in i arrayen men det gör ingen skillnad...

spangoMedlem sedan juni 20008 205 inlägg
#2

Det beror på att du använder strcmp, som namnet antyder är den till för string comparison. Är det tal som ligger i arrayen på platsen $ordning kan du använda

function sort_num_array($a, $b) {
    global $ordning;
    return $a[$ordning] - $b[$ordning];
}

Om du inte vet ifall det kommer vara strängar eller tal får du göra typ

function sort_vartype_array($a, $b) {

    global $ordning;
    $x = $a[$ordning], $y = $b[$ordning];
    if (is_int($x) || is_float($x)) return $x - $y;
    else if (is_string($x)) return strcmp($x, $y);
    else // varken sträng eller tal
}
learnMedlem sedan jan. 20051 130 inlägg
#3

Schysst!

En fråga till; hur gör jag om jag vill kunna ändra ordningen också? Alltså "5,4,3,2,1" istället för "1,2,3,4,5".

spangoMedlem sedan juni 20008 205 inlägg
#4

Antingen använder du http://www.php.net/function.array-reverse eller så vänder du på resultatet av jämförelsen. Typ

function sort_vartype_array($a, $b) {
    global $ordning;
    $x = $a[$ordning], $y = $b[$ordning];
    if (is_int($x) || is_float($x)) return $x - $y;
    else if (is_string($x)) return strcmp($x, $y);
    else // varken sträng eller tal
} 

// Alt. 1
usort($min_array, "sortera_array"); 
if ([I]/* sortera fallande */[/I]) $min_array = array_reverse($min_array); 

// Alt 2
function sort_vartype_desc($a, $b){ return -sort_vartype_array($a, $b); }
if ([I]/* sortera fallande */[/I]) usort($min_array, "sort_vartype_desc"); 
else usort($min_array, "sortera_array");
learnMedlem sedan jan. 20051 130 inlägg
#5

Hmm, en följdfråga; hur ser "sorteringsfunktionen" ut om jag en till dimension i arrayen? Typ så här:

$min_array[1] = array('Namn' => array('Förnamn'=>'Johan', 'Efternamn'=>'Andersson'), 'Ålder'=>'25')

$min_array[2] = array('namn' => array('Förnamn'=>'Richard', 'Efternamn'=>'Svensson'), 'Ålder'=>'28')

Sortera på efternamn. Hur ser funktionen ut? Min gamla håller ju då inte längre:

function sortera_array($a, $b) {

    global $ordning;

    return strcmp($a[$ordning], $b[$ordning]);
    
}

usort($min_array, "sortera_array");
spangoMedlem sedan juni 20008 205 inlägg
#6

Varför inte? Det är bara att se till att $ordning innehåller strängen "Efternamn".

learnMedlem sedan jan. 20051 130 inlägg
#7

Jasså! Ska testa.

learnMedlem sedan jan. 20051 130 inlägg
#8

Nu har jag en riktigt lurigt problem... :)

Om min array istället är uppbyggd enligt följande:

 $min_array[1] = array('Namn' => array('Johan', 'Andersson'), 'Ålder'=>'25')

$min_array[2] = array('Namn' => array('Richard', 'Svensson'), 'Ålder'=>'28')

Hur gör jag då för att sortera på t.ex. efternamnet??

learnMedlem sedan jan. 20051 130 inlägg
#9

Någon problemlösare där ute? :)

spangoMedlem sedan juni 20008 205 inlägg
#10

Du får hitta på nåt fiffigt sätt att se till du jämför $a["Namn"][1] med $b["Namn"][1]. Blir lite bökigt men du har inte mycket val. Sen tycker jag kanske att du borde låta bli att ha såna strukturer, men...

125 ms totalt · 3 externa anrop · v20260731065814-full.30151723
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
123 ms — hämta tråd, inlägg och bilagor (db)