2010-02-24 4 views
0

J'ai quelques objets qui ont 3 options de tri: qualité, quatité et comparaison avec l'autre objet, triés par cet ordre.Tri des tableaux avec des comparaisons cycliques (boucle infinie?)

- (NSComparisonResult) compare: (MyObject *) obj { 
if (self.quality > obj.quality) 
return NSOrderedAscending; 
else if (self.quality < obj.quality) 
return NSOrderedDescending; 

if (self.quantity > obj.quantity) 
return NSOrderedAscending; 
else if (self.quantity < obj.quantity) 
return NSOrderedDescending; 

if ([self betterThan: obj]) 
return NSOrderedAscending; 

if ([obj betterThan: self]) 
return NSOrderedDescending; 

return NSOrderedSame; 
} 

Mon problème est que, la betterthan: méthode peut provoquer un cyclique comparer si les objets ont la même qualité et la quantité, et je veux retourner un ordre de tri dans ce cas.

Par exemple, A, B et C ont la même qualité/quantité, mais

A betterThan: B => YES 
B betterThan: C => YES 
C betterThan: A => YES 

Solutions? Merci.

Répondre

0

Ok, j'ai découvert le bug n'a rien à voir avec le tri (bien que cela semble provenir de cela).

Apparemment, cela fonctionne réellement. Le système arrête le tri s'il y a un blocage.

Merci pour votre temps, de toute façon. :)

0

Vous devez avoir la méthode betterThan: pour retourner NSOrderedSame. Toutes les méthodes qui renvoient NSComparisonResult doivent toujours pouvoir renvoyer les trois options.

Votre méthode ne passera jamais passé le premier si -bloc:

if (self.quality > obj.quality) 
    return NSOrderedAscending; 
else 
    return NSOrderedDescending; //<== returns for both self.quality > obj.quality AND self.quality == obj.quality 

Étant donné que la comparaison doit avoir l'un des trois résultats, mais vous seul test pour une, vous revenez toujours à partir de la méthode dans cette si- bloc. Aucune des autres logiques ne sera jamais utilisée.

Vous devrez imbriquer les if-blocks pour obtenir la logique de filtrage. Testez si elles sont de plus en plus petites et revenez, mais si elles sont identiques, passez au test suivant. Répétez au besoin.

- (NSComparisonResult) compare: (MyObject *) obj { 
    if (self.quality > obj.quality) 
     return NSOrderedAscending; 
    else if (self.quality < obj.quality) 
     return NSOrderedDescending; 
    else { 
     if (self.quantity > obj.quantity) 
      return NSOrderedAscending; 
     else if (self.quantity < obj.quantity) 
      return NSOrderedDescending; 
     else { 
      ... and so on 
     } 
    } 

Je pense que chaque comparaison d'attributs devrait avoir sa propre méthode. Ensuite, vous pouvez les combiner en un grand comparer si vous avez besoin de comparer complètement deux objets de la classe.

On dirait que dans ce cas la méthode betterThan: est votre véritable comparaison de classe.

+0

Oui, vous avez raison, j'ai écrit ce code rapidement. J'ai corrigé cela :) Mais, en supprimant tous les autres compare et colle avec le better Than: comme mon seul comparer, tout ce que j'ai obtenu est écrasé, car il n'arrêtera pas le tri, je crois. Je ne reçois aucune sortie du débogueur, donc je ne peux pas vraiment dire. –

0

Je suis un peu confus concernant votre code et votre question. La fonction de comparaison que vous avez semble comparer seulement la qualité (les deux branches du premier si elles ont des retours). Si vous souhaitez utiliser uniquement betterthan dans votre COMPARE (qui je pense est ce que le problème est votre face ..) Je ferais quelque chose comme:

- (NSComparisonResult) compare: (MyObject *) obj { 
    if ([self betterThan: obj]) 
     if ([obj betterThan: self]) 
      return NSOrderedSame 
     else 
      return NSOrderedAscending; 
    else 
     return NSOrderedDescending 
} 
+0

J'ai pris des précautions pour que 2 objets ne soient jamais meilleurs les uns par rapport aux autres, donc cette situation ne se produira pas vraiment. Mais, pour 3 objets qui peuvent arriver. La fonction de tri obtiendra 2 objets à la fois et les comparera en utilisant la fonction de comparaison. Pour les 3 objets (A, B, C) décrits ci-dessus, mon application se bloque simplement sans sortie de débogueur. –