tri d'un tableau d'objet

Petit nouveau ! | 4 Messages

20 oct. 2009, 22:47

Bonjour,

Je viens solliciter l'aide des gros balèzes de PhPFrance car j'ai un petit souci.

Je vais vous décrire mes classes et ce que j'essaie de faire :
Une classe Jeu permettant de construire un objet Jeu correspondant au jeu enregistré dans ma BDD, avec les getters et setters appropriés

Code : Tout sélectionner

class Jeu{ private $numjeu; private $nomjeu; private $idgenre; private $localisation; private $description; private $note; }
Une classe TabJeu qui me permet de générer un tableau d'objets jeu à partir des jeux enregistrés dans ma BDD

Code : Tout sélectionner

class TabJeu { private $tabjeux; private $nbjeux; }
lorsque je crée mon TabJeu il est donc de la forme

Code : Tout sélectionner

TabJeu[0]=objet jeu1; TabJeu[1]=objet jeu2; TabJeu[2]=objet jeu3; etc..
Je voudrai pouvoir trier ce tableau de manière successive, en gardant en mémoire le tri précédent.

Si je fais un premier uasort par nom de jeu sur le tableau, le résultat apparait bien trié par nom.
Mais si je fais un second uasort sur le genre de jeu, le tableau est bien trié par genre, mais pour chaque genre les jeux ne sont plus triés par nom.

J'ai essayé le multisort, mais je ne comprends pas comment le faire fonctionner avec mon tableau d'objets...

Merci d'avance pour votre aide !

:priere:

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

22 oct. 2009, 13:53

Tu ne peux pas faire un tri en sortie de la base ?

A quoi sert vraiment la classe TabJeux ? pourquoi ne pas utiliser directement le tableau ?

Moi je filtrerai par genre, je ferais un tableau par genre et je trierai sur les noms à l'intérieur de celui-là.

$tabJeux['baston'] = Array(jeu1, jeu2 etc)
$tabJeux['plateforme'] = Array(jeu1, jeu2 etc)

En Java tu pourrais faire ça facilement en utilisant les Comparator et les méthodes de Collection.utils mais en PHP je ne sais pas, cherche s'il n'y a pas des classes créées pour manipuler des collections d'objets.

Administrateur PHPfrance
Administrateur PHPfrance | 3131 Messages

22 oct. 2009, 14:40

voir : usort, uksort, uasort seront tes amis :)

Petit nouveau ! | 4 Messages

22 oct. 2009, 20:03

voir : usort, uksort, uasort seront tes amis :)
J'ai déjà regardé ces fonctions mais je n'ai pas trouvé mon bonheur (ou alors je n'ai pas compris comment faire !)

C'est vrai que Tabjeu n'est pas forcément très utile... Par contre je ne veux justement pas refaire d'appel à la BDD (enfin c'est que je fais pour l'instant faute de mieux...). J'en fais un pour charger tous les jeux lors de l'affichage de la liste, si je dois en refaire un à chaque fois qu'on clic que un bouton de tri, ça prend trop de temps ! et puis c'est dommage sachant que toutes les données ont déjà été récupérées...

Merci quand même pour les réponses :) si vous avez d'autres suggestions, je suis preneuse !

Administrateur PHPfrance
Administrateur PHPfrance | 3131 Messages

22 oct. 2009, 22:13

TabJeu[0]=objet jeu1;
TabJeu[1]=objet jeu2;
TabJeu[2]=objet jeu3;
Et bien c'est simple, tu écris le comparateur correspondant.

Par exemple, si tu veux trier par genre puis par nom :
function compare_jeu_genre_nom(Jeu $a, Jeu $b)
{
  $compare_genre = strnatcasecmp($a->genre, $b->genre);
  if ($compare_genre == 0)
  {
    // tri secondaire
    return strnatcasecmp($a->nom, $b->nom);
  }
  return $compare_genre;
}
puis simplement usort($tableau, 'compare_jeu_genre_nom').

Tiens, tu peux même te créer un "générateur de fonctions de comparaison d'objets" :
class ObjectComparator
{

  // Champs qu'on va comparer
  private $fields = array();
 
  // Tri croissant/décroissant
  protected $ascending = true;

  // Constructeur
  // $fields la liste des champs à comparer, format $fieldName => $compareFunction
  public function __construct($fields, $asc = true)
  {
    if (!is_array($fields))
    {
      $fields = array($fields => 'strnatcasecmp');
    }
    $this->fields = $fields;
  }

  // La fonction de comparaison qui renvoie -1/0/1
  // à utiliser avec usort()
  public function compare($a, $b)
  {
    $result = 0;
    foreach ($this->fields as $field => $compare)
    {
      $result = call_user_func($compare, $a->$field, $b->$field);
      if ($result != 0)
      {
        return $result;
      }
    }
    return $this->ascending ? $result : -$result;
  }

  // Trier un tableau avec mon comparateur
  public function sort(&$array)
  {
    usort($array, array($this, 'compare'));
  }

}

// Exemple d'utilisation :
$comparator = new ObjectComparator(array(
  'genre' => 'strcmp',
  'nom' => 'strnatcasecmp',
));
$comparator->sort($tableau);

Petit nouveau ! | 4 Messages

22 oct. 2009, 23:18

Merci beaucoup, je tenterai ça demain et je vous tiens au courant ! :D

Petit nouveau ! | 4 Messages

24 oct. 2009, 16:52

Merci pour la réponse, j'ai réussi à me débrouiller avec ça :)