webForumDet fria alternativet

Sortera en array - siffror blir fel

PHP

9 svar · 758 visningar · startad av learn

Medlem sedan jan. 20051 130 inlägg
Frågan#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...

Medlem 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
}
Medlem 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".

Medlem 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");
Medlem 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");
Medlem sedan juni 20008 205 inlägg
#6

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

Medlem sedan jan. 20051 130 inlägg
#7

Jasså! Ska testa.

Medlem 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??

Medlem sedan jan. 20051 130 inlägg
#9

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

Medlem 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...

269 ms totalt · 3 externa anrop · v20260731065814-full.eb2a8c97
133 ms — deklarationer (db)
0 ms — hämta statistik (cache)
134 ms — hämta tråd, inlägg och bilagor (db)