Tri d'un tableau d'objets SimpleXML
J'ai lu ce que j'ai trouvé sur Stackoverflow et je suis toujours dans le flou sur ce.
J'ai un tableau de SimpleXML objets à quelque chose comme ceci:
array(2) {
[0]=>
object(SimpleXMLElement)#2 (2) {
["name"]=>
string(15) "Andrew"
["age"]=>
string(2) "21"
}
[1]=>
object(SimpleXMLElement)#3 (2) {
["name"]=>
string(12) "Beth"
["age"]=>
string(2) "56"
}
}
Et je veux être en mesure de trier par quoi que ce soit de la colonne, par ordre croissant ou décroissant. Quelque chose comme:
sort($data, 'name', 'asc');
Où je peux passer dans le tableau ci-dessus des objets et de les trier en fonction de la valeur de celui de la clé que j'aime.
Pour référence, un semblable .NET solution serait le long de ces lignes:
XmlSortOrder order = XmlSortOrder.Ascending;
if ( sortDirection == "asc" ) {
order = XmlSortOrder.Ascending;
}
expression.AddSort( columnSortingOn + "/text()", order,
XmlCaseOrder.UpperFirst, "en-us", XmlDataType.Text );
J'ai vu des gens dire
"Utilisation usort"
Suivie d'un exemple de base du manuel PHP mais ce n'est pas vraiment l'expliquer. Au moins pas pour moi. J'ai aussi vu des gens suggèrent d'utiliser une bibliothèque externe comme SimpleDOM mais je veux éviter d'utiliser quelque chose d'externe (apparemment, même si je ne peux pas encore le résoudre) peu de chose.
Toute aide est appréciée, Merci!
OriginalL'auteur rg88 | 2010-01-22
Vous devez vous connecter pour publier un commentaire.
Je pense que les gens ce qui suggère d'utiliser SimpleDOM serait moi. 🙂
J'ai écrit SimpleDOM::sort() exactement pour cette situation, parce que, pour trier SimpleXMLElements par un arbitrage de l'expression (ou l'arbitraire des expressions de), vous devez utiliser
array_multisort()
ce qui est ennuyeux et ne sera pas vous apprendre quelque chose d'utile.Voici la version courte de la façon dont cela fonctionne: d'abord vous créer un réseau proxy de clé=>paires de valeur correspondant à chaque SimpleXMLElement et la valeur avec laquelle ils vont être triés. Dans votre exemple, si vous souhaitez trier par
<age/>
, le tableau seraitarray(21, 56)
. Vous pouvez ensuite appelerarray_multisort()
avec le "réseau proxy" comme premier argument, suivi d'un nombre quelconque de le tri des modificateurs comme SORT_DESC ou SORT_NUMERIC puis, finalement, le tableau que vous souhaitez trier, qui sera passé par référence.Vous allez vous retrouver avec quelque chose comme ça:
Mais vraiment, au lieu de les surcharger de vous-même avec plus de code que vous aurez à maintenir et, éventuellement, de se retrouver de réécriture
array_multisort()
dans l'espace utilisateur, vous devez tirer parti de solutions existantes. Il n'y a rien d'intéressant dans un tel algorithme de tri ou de routine, votre temps serait mieux dépensé sur quelque chose qui n'existe pas déjà.Je ne suis pas presistent, seulement cohérent dans le plaidoyer pour la réutilisation du code. Si l'extrait de code que j'ai posté ci-dessus fonctionne pour vous, puis par tous les moyens utilisez-le. Ou de l'utilisation de fermetures, si vous préférez, tout ce qui fonctionne pour vous. Comme vous l'avez dit, votre but est de trouver une solution qui vous permettra de passer à la prochaine pierre d'achoppement et ne vous demandera pas de regarder en arrière plus tard.
Que "persistants" qui était censé être gratuit. Je suis vendu sur SimpleDOM. Il fonctionne, tout simplement. Rapide. Great stuff, Josh.
Oh merci 🙂 Ne vous inquiétez pas, je n'ai pas de prendre infraction
Heureux vous avez une solution. Avoir les réponses à expliquer et/ou d'une démonstration usort() été assez bon pour vous aider à les comprendre? (Et ne pas utiliser une bibliothèque externe qui semblait être une grande partie de votre question.)
OriginalL'auteur Josh Davis
La
usort
fonction vous permet d'indiquer à PHPIl n'a rien de spécifiquement à faire avec SimpleXML. C'est une fonction générique pour le tri PHP intégré dans le tableau de collecte de données.
Vous devez écrire une fonction, une méthode d'instance, ou une méthode statique pour trier le tableau. Le deuxième argument de usort accepte un Fonction PHP, qui est un pseudo-type qui permet de spécifier la fonction, la méthode d'instance, ou une méthode statique.
La fonction que vous écrivez va accepter deux arguments. Ces deux valeurs différentes à partir de votre tableau de
Vous avez besoin d'écrire cette fonction pour retourner l'une des trois valeurs.
Lorsque vous appelez usort, PHP sera exécuté par le biais de votre tableau, l'appel de votre fonction de tri/méthode (dans ce cas
cmp
encore et encore jusqu'à ce que le tableau est trié. Dans votre exemple, $a et $b sera SimpleXML objets.OriginalL'auteur Alan Storm
J'étais prêt à recommander
usort()
jusqu'à ce que j'ai compris vous avez déjà me battre pour elle. Depuis que des exemples de code n'est pas encore fait beaucoup de bien dans le passé, je vais essayer de vous expliquer dans un anglais courant et nous espérons que vous aurez fait dans la bonne direction.En utilisant
usort()
, vous créez votre propre généré par l'utilisateur "algorithme". Leusort()
les appels de fonction de votre propre fonction de comparaison pour déterminer comment chacun de vos objets se rapporte à l'un l'autre. Lors de l'écriture de votre fonction de comparaison, vous aurez passé en deux objets à l'intérieur de votre tableau. Avec ces deux objets, vous retourner un résultat qui indique essentiellementusort()
si le premier objet estLESS THAN
,EQUAL TO
, ouGREATER THAN
le deuxième objet. Vous faites cela en retournant -1, 0 ou 1 (respectivement). C'est tout. Vous n'avez qu'à vous préoccuper de la façon dont les deux objets à comparer les uns aux autres et le tri réelle de la mécanique sont traitées parusort()
pour vous.Ok, maintenant pour un semi-exemple pratique:
C'est à peu près l'exemple dans le Manuel PHP, mais nous espérons que cela a du sens en contexte. Permettez-moi de savoir si je suis pas sur d'être clair sur une chose.
Vous pouvez utiliser une variable globale pour spécifier la colonne qui sera utilisée dans la comparaison (garder les types de données à l'esprit de les comparer entre des chaînes de caractères et de chiffres). Je n'avais jamais vraiment recommander quelqu'un l'utiliser de variables globales, donc plus idéalement, mise en œuvre dans une classe et l'utilisation d'une variable de membre pour spécifier la colonne. Je n'ai jamais utilisé
usort()
de cette façon, alors je ne peux pas promettre ça marchera. Je voudrais exécuter un test rapide si j'avais plus de temps.Id dire de l'emballer dans une classe est l'idéal intermédiaire. Peut-être en élargissant ArrayObject.
OriginalL'auteur Bret Kuhns
Josh Davis solution ne semble pas fonctionner lors du chargement d'un fichier XML via:
J'obtiens l'erreur suivante:
Warning: array_multisort() [function.array-multisort]: Argument #3 is expected to be an array or a sort flag in /home/usr/public_html/feeds/deadlines.php on line 8
Il concerne: array_multisort($sort_proxy, de l'ordre de$, $noeuds);
OriginalL'auteur H. Ferrence
Voici un autre exemple de l'utilisation de
usort()
. Celui-ci vous permet de spécifier la variable d'objet et le sens de tri:Code de Test,
OriginalL'auteur GZipp
c'est un vieux thread mais, voici ma solution que l'utiliser pour extraire des informations à partir d'un flux rss afin de les trier par titre
OriginalL'auteur user3116221