2009-09-29 7 views

Répondre

4

LINQ aux objets:

using System; 
using System.Linq; 
using System.Drawing; 

class Example 
{ 
    static void Main() 
    { 
     Point[] points = new Point[] 
     { 
      new Point(2,2), 
      new Point(3,1), 
      new Point(3,2), 
      new Point(1,3) 
     }; 

     var sortedPoints = points 
       .OrderBy(p => p.X) 
       .ThenBy(p => p.Y); 
    } 
} 
+1

mais ce code trie deux fois, n'est ce pas ?? –

13

Non, vous ne pouvez pas simplement deux fois sorte que l'algorithme NET Framework Trier() est une sorte instable, ce qui signifie que lorsque vous triez des objets, l'ordre dans lequel ils se trouvaient à l'origine n'est pas pris en compte, c'est-à-dire que lorsque deux éléments sont égaux, leur position l'un par rapport à l'autre ne sera pas définie.

Ce que vous devez faire est de mettre en œuvre un IComparer personnalisé pour la classe que vous essayez de trier et d'utiliser ce comparateur lors du tri de votre collection:

class PointComparer : IComparer<Point> 
{ 
    public int Compare(Point x, Point y) 
    { 
     if (x.Y != y.Y) 
     { 
      return x.Y - y.Y; 
     } 
     else 
     { 
      return x.X - y.X; 
     } 
    } 
} 

Utilisation:

List<Point> list = ...; 
list.Sort(new PointComparer()); 
+0

+1 Pour mémoire, c'est environ deux fois plus rapide que ma solution LINQ. –

+1

Y & X sont de type double ... utilisent 'return xYCompareTo (yY);' et 'return xXCompareTo (yX);' respectivement dans les instructions de retour – Rado

+0

Ce sont 'Point' pas' PointF' – Coincoin

0

je peux Ne pas dire à partir de la question si "trier à la fois verticalement et horizontalement" vous voulez les trier "d'abord verticalement puis horizontalement" (mieux fait en un passage, comme l'ont dit les autres réponses) ou si vous voulez les trier les points dans l'avion ont tendance à être à proximité dans la liste. Si c'est le dernier, il y a space filling curves qui peut être beaucoup mieux qu'une approche purement verticale-puis-horizontale.

Questions connexes