Question

Ceci est une question très ésotérique, mais je suis vraiment curieux. J'utilise usort pour la première fois aujourd'hui au cours des années, et je suis particulièrement intéressé par ce qui se passe exactement. Supposons que j'ai le tableau suivant:

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

Je pourrais trier cela avec usort:

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

Je ne suis pas 100% clair sur ce qui se passe avec les deux paramètres $ a et $ b. Quels sont-ils et que représentent-ils. Je veux dire, je pourrais supposer que $ représente l'élément courant dans le tableau, mais ce qui est exactement ce à obtenir par rapport? Qu'est-ce que $ b?

Je pourrais augmenter mon tableau pour inclure des chaînes:

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

Et exécutez la commande suivante:

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

Et cela trier mes enfants-réseaux par ordre alphabétique en fonction de la [0] valeur d'index. Mais cela ne fournit aucune clarté sur ce que $ a et $ b sont. Je sais seulement que le match le modèle que je recherche.

Quelqu'un peut-il offrir une certaine clarté sur ce qui se passe réellement?

Était-ce utile?

La solution

Pour trier tout ce que vous avez besoin d'un moyen de comparer deux éléments et savoir si l'on vient avant l'autre. Voici ce que vous fournissez à usort. Cette fonction sera passé deux éléments de votre tableau d'entrée, et renvoie l'ordre dans lequel ils doivent être.

Une fois que vous avez un moyen de comparer deux éléments, vous pouvez utiliser tri-algorithme de-votre-choix .

Si vous ne connaissez pas, vous voudrez peut-être regarder comment un simple algorithme naïf comme bubblesort utiliserait une fonction de comparaison.

Dans les coulisses, PHP utilise un quicksort .

Autres conseils

La définition exacte d'un $ et $ b dépendra de l'algorithme utilisé pour trier le tableau. Pour trier tout ce que vous devez avoir un moyen de comparer deux éléments, qui est ce que la fonction de rappel est utilisé. Certains algorithmes de tri peuvent commencer n'importe où dans le tableau, d'autres peuvent commencer que dans une partie spécifique, donc il n'y a pas de fixe sens dans $ et $ b autre que ce sont deux éléments du tableau qui doivent comparer en fonction de l'algorithme en cours.

Cette méthode peut être utilisée pour faire la lumière sur laquelle algorithme PHP utilise.

<?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);
?>

Sortie

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
)

De la sortie et à la recherche à la source, nous pouvons voir le genre utilisé est en effet un quicksort la mise en œuvre, vérifier Zend / zend_qsort.c dans la source de PHP (la version est liée à un peu vieux, mais n'a pas beaucoup changé).

Il choisit le pivot au milieu de la matrice, dans ce cas 18, puis il a besoin pour réorganiser la liste de sorte que tous les éléments qui sont moins (en accord avec la fonction de comparaison en cours d'utilisation) que le pivot devant le pivot et de sorte que tous les éléments plus que le pivot viennent après, nous pouvons le voir faire que quand il compare tout à 18 au début.

Quelques autres explications schématique.

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 () ou uasort () ont un bug sentiment humain sur le résultat de tri. Voir le segment de code:

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);

le résultat est:

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

Avez-vous vu le problème? Non? Ok, permettez-moi de l'expliquer. Les trois originaux « 9 » elments sont en ordre de clé: 2,3,4. Mais, dans la suite, les trois éléments « 9 » sont maintenant dans l'ordre des clés: 4,3,2, à savoir des éléments de même valeur sont dans l'ordre inverse après la clé de tri

.

Si l'élément est seulement une valeur unique, comme dans l'exemple ci-dessus, il est très bien avec nous. Toutefois, si l'élément est composé valeur, alors il pourrait causer des bogues sentiment humain. Voir un autre segment de code. Nous devons trier beaucoup de points horizontalement, à savoir les trier par ordre croissant basées sur valeur de coordonnée x ordre:

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);

le résultat est:

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 ) )

Vous voyez ' I love Lara Croft et Tomb Raider ' devient ' I Lara Croft amour et Tombraider .

Je l'appelle bug sentiment humain parce que cela dépend de ce cas que vous utilisez et comment vous vous sentez qu'il devrait être trié dans le monde réel lorsque les valeurs comparées sont les mêmes.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top