Préserver l'ordre des clés (tri stable) lors du tri avec PHP uasort
Cette question est en fait inspiré d'un autre ici et je voulais la développer un peu.
Avoir un tableau associatif en PHP il est possible de trier ses valeurs, mais où les valeurs sont égales à préserver la clé d'origine, en utilisant un (ou plusieurs) de PHP intégré dans la fonction de tri?
Voici un script que j'ai utilisé pour tester des solutions possibles (n'ai pas trouvé d'):
<?php
header('Content-type: text/plain');
for($i=0;$i<10;$i++){
$arr['key-'.$i] = rand(1,5)*10;
}
uasort($arr, function($a, $b){
//sort condition may go here //
//Tried: return ($a == $b)?1:($a - $b); //
//Tried: return $a >= $b; //
});
print_r($arr);
?>
Piège: Parce que les touches sont classés dans le tableau d'origine, s'il vous plaît ne pas être tenté de suggérer le tri par clé pour restaurer l'ordre d'origine. J'ai fait l'exemple avec eux condamnée à être plus facile de vérifier visuellement leur ordre dans la sortie.
- En d'autres termes, la solution à cette question est un stable algorithme de tri, qu'aucun de PHP sur les algorithmes de tri sont, soi-disant.
- Je me doutais bien que beaucoup, mais je voudrais une réponse définitive et/ou une solution de contournement possible.
- Est-il une raison pour utiliser biult fonctions seulement ?
- php.net/manual/en/array.sorting.php - Si l'une de ces fonctions de tri, évalue deux membres de l'égalité, l'ordre n'est pas défini (le tri n'est pas stable).
- Tout d'abord, je voudrais savoir si c'est possible en utilisant l'un de PHP des fonctions. Deuxièmement, je voudrais voir une alternative.
- Regardez: notmysock.org/blog/php/schwartzian-transform.html il résout mon problème.
Vous devez vous connecter pour publier un commentaire.
Depuis PHP ne supporte pas le tri stable après PHP 4.1.0, vous devez écrire votre propre fonction.
Ce qui semble faire ce que vous demandez: http://www.php.net/manual/en/function.usort.php#38827
On peut également trouver des ce fil du forum intéressant.
uasort
avec un enveloppé fonction de comparaison, et prend 1/5ème du temps que cette réponse (qui est une excellente illustration, mais inneficient).array_multisort
est très pratique, il suffit d'utiliser un ensemble ordonné de gamme comme le deuxième tableau ($order
est que temporaire, il sert à l'ordre de l'équivalent des éléments du premier tableau dans l'ordre d'origine):Sortie
J'ai utilisé des données de test avec pas-clés des commandes de démontrer qu'il fonctionne correctement. Néanmoins, ici, c'est la sortie de votre script de test:
Inconvénient
Il ne fonctionne qu'avec des comparaisons, vous ne pouvez pas utiliser votre propre fonction de comparaison. Les valeurs possibles (deuxième paramètre de
array_multisort()
) sont:array_sort($a, SORT_ASC, array_keys($a), SORT_NATURAL)
pour une forme similaire de la stabilité de tri. Qui change[ 'Sick' => 8, 'Vacation' => 12, 'Other' => -4, 'Holiday' => 0, 'Bereavement' => 0 ]
à[ 'Other' => -4, 'Bereavement' => 0, 'Holiday' => 0, 'Sick' => 8, 'Vacation' => 12 ]
Référence pour l'avenir, j'ai mis un ensemble de tri stable variantes de builtin fonctions de PHP sur Github: https://github.com/vanderlee/PHP-stable-sort-functions, basé sur @Jack solution et quelques autres trucs.
Par souci d'exhaustivité, vous devriez également vérifier la Schwartzian transformer:
L'algorithme de tri par défaut de PHP fonctionne très bien avec les tableaux, à cause de cela:
Si vous souhaitez utiliser vos propres critères de tri que vous pouvez utiliser
uasort()
ainsi:C'est une solution à l'aide de laquelle vous pouvez atteindre tri stable dans la fonction usort
Juste pour compléter les réponses, avec des cas très spécifiques. Si les clés du tableau de
$array
sont par défaut, alors qu'un simplearray_values(asort($array))
est suffisante (ici, par exemple, dans l'ordre croissant)