7
votes

Tri d'un tableau d'objets SimplexML

J'ai lu ce que j'ai trouvé sur Stackoverflow et je suis toujours difficile à ce sujet.

J'ai un tableau d'objets simplexml quelque chose comme ceci: xxx

Et je veux être capable de trier par toute colonne, ascendant ou descendante. Quelque chose comme: xxx

où je peux passer dans la matrice ci-dessus d'objets et trier par la valeur de la clé que j'aime.

Pour référence, une solution similaire .NET serait le long de ces lignes: xxx

J'ai vu des gens dire

"Utilisez usort"

suivi d'un exemple de base du manuel PHP, mais cela ne l'explique pas vraiment. Au moins pas pour moi. J'ai également vu des gens suggèrent d'utiliser une bibliothèque externe comme SimpleDom, mais je veux éviter d'utiliser quelque chose d'extérieur pour cela (apparemment, bien que je ne puisse pas encore résoudre) la petite chose.

Toute aide est appréciée, merci!


0 commentaires

5 Réponses :


2
votes

J'étais prêt à recommander USort () code> jusqu'à ce que je réalisais que tu m'as déjà battus. Étant donné que les exemples de code n'ont pas fait beaucoup de bien dans le passé, je vais essayer de simplement l'expliquer en anglais clair et, espérons-le que cela vous permettra de pointer dans la bonne direction.

En utilisant USORT () Code>, vous créez votre propre "algorithme" généré par l'utilisateur. La fonction USort () code> appelle votre propre fonction de comparaison pour déterminer la manière dont chacun de vos objets se rapporte les uns aux autres. Lorsque vous écrivez votre fonction de comparaison, vous serez passé dans deux objets dans votre tableau. Avec ces deux objets, vous retournez un résultat qui indique essentiellement USort () code> si le premier objet est moins que code>, égal à code> ou Supérieur à code> le deuxième objet. Vous faites cela en retournant -1, 0 ou 1 (respectivement). C'est ça. Il vous suffit de vous préoccuper de la façon dont deux objets se comparent les uns aux autres et les mécanismes de tri réels sont géré par USort () code> pour vous. P>

OK, maintenant pour une semi-pratique Exemple: P>

function myCompare($obj1, $obj2) {
    if($obj1->someInt == $obj2->someInt) {
        return 0; // equal to
    } else if($obj1->someInt < $obj2->someInt) {
        return -1; // less than
    } else {
        return 1; // greater than
    }
}

$myArray = {a collection of your objects};

usort($myArray, 'myCompare');


3 commentaires

Le seul problème avec ceci est qu'il a besoin de faire des fonctions explicites pour chaque propriété, car il souhaite pouvoir les trier par une éventuelle valeur d'élément XML. Par conséquent, il doit proposer un intermédiaire qui permettra d'utiliser une propriété fournie et une commande au moment de l'appel.


Vous pouvez utiliser une variable globale pour spécifier quelle colonne sera utilisée dans la comparaison (gardez les types de données à l'esprit à comparer entre chaînes et chiffres). Je ne recommanderais jamais que quelqu'un utilise des globaux, donc plus idéalement, implémentez-le dans une classe et utilisez une variable de membre pour spécifier la colonne. Je n'ai jamais utilisé USort () de cette façon, donc je ne peux pas promettre que cela fonctionnera. Je dirigerais un test rapide si j'avais plus de temps.


ID Dites l'enveloppant dans une classe est l'intermédiaire idéal. Peut-être en prolongeant ArrayObject.



4
votes

La fonction USort code> vous permet de dire PHP

Hey, vous! Trier ce tableau Je vous donne cette fonction que j'ai écrit. P> blockQuote>

Il n'a rien spécifiquement à faire avec SimplexML. C'est une fonction générique pour trier la collecte de données de tableau intégrée PHP. P>

Vous devez écrire une fonction, une méthode d'instance ou une méthode statique pour trier la matrice. Le deuxième argument à usort accepte un Rappel PHP , qui est un pseudo-type qui vous permet de spécifier quelle fonction, quelle méthode d'instance ou quelle méthode statique. p>

La fonction que vous écrivez acceptera deux arguments. Ce seront deux valeurs différentes de votre tableau p> xxx pré>

Vous devez écrire cette fonction pour renvoyer l'une des trois valeurs de trois. P>

If $a == $b, return 0
If $a > $b, return -1
if $a > $v, return 1  


0 commentaires

1
votes

Voici un autre exemple d'utilisation USort () . Celui-ci vous permet de spécifier la variable d'objet et la direction de tri: xxx

code de test; xxx


1 commentaires

Pourquoi $ Sort_func = fonction ($ obj_1, $ obj_2) utilise ($ trient_field, $ trit_direction) donnez-moi une erreur de syntaxe?



4
votes

Je suppose que les gens suggèrent d'utiliser SimpleDom seraient moi. :)

J'ai écrit SimpleDom :: Trier () Exactement pour cette situation, car afin de trier les simplexmlellexes par une expression arbitrale (ou des expressions arbitraires), vous devez utiliser array_multisort () qui est ennuyeux et ne vous apprendra rien d'utile. < / P>

Voici la version courte de la façon dont cela fonctionne: vous créez d'abord un réseau de proxy de clé => Value paires correspondant à chaque simplexmlelement et la valeur avec laquelle ils seront triés. Dans votre exemple, si vous souhaitez les trier par <Âge /> , le tableau serait Array (21, 56) . Ensuite, vous appelez array_multisort () avec le "tableau proxy" comme premier argument, suivi d'un nombre quelconque de Modificateurs de tri tels que Sort_Desc ou Sort_Numérique, puis enfin le tableau que vous souhaitez trier, qui sera transmis par référence.

Vous finirez par quelque chose comme ça: xxx

mais vraiment, au lieu de vous charger de plus de code, vous devez gérer et éventuellement mettre fin à la réécriture array_multisort () UtilisateursPace, vous devez exploiter des solutions existantes. Il n'y a rien d'intéressant dans un tel algorithme / routine de tri, votre temps serait mieux dépensé pour quelque chose qui n'existe pas déjà.


5 commentaires

Eh bien Heck Josh, vous êtes persistant! Je suppose que je vais essayer comme cela me permettrait de passer à la prochaine pierre tombale et je pourrais probablement l'utiliser dans d'autres endroits sur ce projet.


Je ne suis pas préreinte, seulement cohérent pour préconiser la réutilisation du code. Si l'extrait que j'ai posté ci-dessus fonctionne pour vous, alors par toutes les méchants, veuillez l'utiliser. Ou utilisez des fermetures si vous préférez, quel que soit ce qui fonctionne pour vous. Comme vous l'avez dit, votre objectif est de trouver une solution qui vous permettra de passer au prochain obstacle et ne vous obligera pas à regarder en arrière plus tard.


Que "persistant" était censé être complémentaire. Je suis vendu sur SimpleDom. Ça marche juste. Rapide. Grands trucs, Josh.


@ gaoshan88 - content que vous ayez une solution. Avez-vous des réponses expliquant et / ou démontrer Usort () ont été assez bonnes pour vous aider à le comprendre? (Que, avec non pas d'utiliser une bibliothèque externe, semblait être une grande partie de votre question.)


@Gzipp - Oui, la plupart des commentaires contenaient ici des bits utiles, les vôtres inclus (que j'ai voté). La raison pour laquelle j'ai choisi Josh, c'est qu'il n'a pas seulement fait un bon argument pour utiliser sa bibliothèque, il comprenait une solution autonome qui fonctionne.



1
votes

C'est un vieux fil, mais voici ma solution qui utilise pour extraire des informations à partir d'un flux RSS afin de trier par titre xxx


0 commentaires