Domanda

Questa è una domanda davvero esoterica, ma sono sinceramente curioso.Sto usando usort per la prima volta dopo anni e sono particolarmente interessato a cosa sta succedendo esattamente.Supponiamo di avere il seguente array:

$myArray = array(1, 9, 18, 12, 56);

Potrei ordinarlo con usort:

usort($myArray, function($a, $b){
  if ($a == $b) return 0;
  return ($a < $b) ? -1 : 1;
});

Non sono chiaro al 100% cosa sta succedendo con i due parametri $a e $b.Cosa sono e cosa rappresentano.Voglio dire, potrei supporre che $a rappresenti l'elemento corrente nell'array, ma a cosa viene paragonato esattamente questo?Cos'è $b?

Potrei aumentare il mio array per includere stringhe:

$myArray = array(
  array("Apples", 10),
  array("Oranges", 12),
  array("Strawberries", 3)
);

Ed esegui quanto segue:

usort($myArray, function($a, $b){
  return strcmp($a[0], $b[0]);
});

E questo ordinerebbe i miei array figli in ordine alfabetico in base al valore dell'indice [0].Ma questo non offre alcuna chiarezza su cosa siano $a e $b.So solo che corrisponde allo schema che sto cercando.

Qualcuno può fare chiarezza su ciò che sta realmente accadendo?

È stato utile?

Soluzione

Per ordinare qualsiasi cosa hai bisogno di un mezzo per confrontare due elementi e capire se uno viene prima dell'altro.Questo è ciò che fornisci a noirt.A questa funzione verranno passati due elementi dall'array di input e restituirà l'ordine in cui dovrebbero essere.

Una volta che hai un mezzo per confrontare due elementi, puoi usare algoritmo di ordinamento scelto da te.

Se non hai familiarità, ti potrebbe interessare vedere come piace un semplice algoritmo ingenuo bubblesort utilizzerebbe una funzione di confronto.

Dietro le quinte, PHP utilizza a Quicksort.

Altri suggerimenti

L'esatta definizione di $ ae $ b dipenderà dalla algoritmo utilizzato per ordinare l'array. Per ordinare qualsiasi cosa bisogna avere un mezzo per confrontare due elementi, questo è ciò che la funzione di callback viene utilizzato per. Alcuni algoritmi di ordinamento può iniziare in qualsiasi parte della matrice, gli altri possono iniziare solo in una parte specifica di esso quindi non c'è alcun fisso significato in $ ae $ b diverso da quello che sono due elementi nella matrice che devono essere paragonato secondo l'algoritmo corrente.

Questo metodo può essere usato per far luce su cui algoritmo PHP sta utilizzando.

<?php

$myArray = array(1, 19, 18, 12, 56);

function compare($a, $b) {
    echo "Comparing $a to $b\n";
    if ($a == $b) return 0;
    return ($a < $b) ? -1 : 1;
}

usort($myArray,"compare");
print_r($myArray);
?>

Output

vinko@mithril:~$ php sort.php
Comparing 18 to 19
Comparing 56 to 18
Comparing 12 to 18
Comparing 1 to 18
Comparing 12 to 1
Comparing 56 to 19
Array
(
    [0] => 1
    [1] => 12
    [2] => 18
    [3] => 19
    [4] => 56
)

Dal uscita e guardando la fonte possiamo vedere il tipo usato è davvero un quicksort implementazione, verificare la presenza di Zend / zend_qsort.c nella sorgente PHP (il legato alla versione è un po 'vecchio, ma non è cambiato molto).

Si riprende il perno al centro della matrice, in questo caso 18, quindi ha bisogno di riordinare l'elenco in modo che tutti gli elementi che sono meno (in base alla funzione di confronto in uso) del pivot venire prima il perno e in modo che tutti gli elementi maggiori di perno venire dopo di esso, possiamo vedere che farlo quando si paragona tutto a 18 in un primo momento.

Alcuni ulteriori spiegazioni schematico.

Step 0: (1,19,18,12,56); //Pivot: 18, 
Step 1: (1,12,18,19,56); //After the first reordering
Step 2a: (1,12);         //Recursively do the same with the lesser, here 
                         //pivot's 12, and that's what it compares next if 
                         //you check the output.
Step 2b: (19,56);        //and do the same with the greater

usort () o uasort () hanno un umano-sensazione bug risultati ordinato. Vedere il segmento di codice:

function xxx($a,$b) { if ($a==$b) return 0; else return $a<$b?-1:1; }
$x=array(1=>10,2=>9,3=>9,4=>9,5=>6,6=>38);
uasort($x,'xxx');
print_r($x);

il risultato è il seguente:

Array ( [5] => 6 [4] => 9 [3] => 9 [2] => 9 [1] => 10 [6] => 38 )

Non si vede il bug? No? Ok, mi permetta di spiegare. I tre '9' elments originali sono in ordine chiave: 2,3,4. Ma nel risultato, i tre elementi '9' sono ora in ordine chiave: 4,3,2, elementi cioè uguale valore sono in ordine inverso chiave dopo l'ordinamento

.

Se l'elemento è unico valore singolo, come nell'esempio sopra, è bene con noi. Tuttavia, se l'elemento è il valore residuo, allora potrebbe causare bug umano-sentimento. Vedi altri segmenti di codice. Siamo ordinare molti punti orizzontalmente, cioè ordinarli riferiscono al senso crescente ascissa ordine di valore:

function xxx($a,$b) { if ($a['x']==$b['x']) return 0; else return $a['x']<$b['x']?-1:1; }
$x=array(1=>array('x'=>1, 'v'=>'l'),2=>array('x'=>9, 'v'=>'love'),
       3=>array('x'=>9,  'v'=>'Lara'),4=>array('x'=>9,  'v'=>'Croft'),
       5=>array('x'=>15,  'v'=>'and'),6=>array('x'=>38,  'v'=>'Tombraider'));
uasort($x,'xxx');
print_r($x);

il risultato è il seguente:

Array ( [1] => Array ( [x] => 1 [v] => l ) [4] => Array ( [x] => 9 [v] => croft ) 
             [3] => Array ( [x] => 9 [v] => Lara ) [2] => Array ( [x] => 9 [v] => love )
             [5] => Array ( [x] => 15 [v] => and ) [6] => Array ( [x] => 38 [v] => Tombraider ) )

Si vede ' amo Lara Croft e Tombraider ' diventa ' I amore Croft Lara e Tombraider ' .

Io lo chiamo umano-sensazione bug perché dipende da quale caso si usa e come si sente dovrebbe essere ordinata in mondo reale quando i valori confrontati sono gli stessi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top