2010-04-20 3 views
4

j'ai une liste d'éléments dans une liste générique:Pourquoi ma méthode List.Sort en C# inverse l'ordre de ma liste?

  • A1 (index de tri 1)
  • A2 (index de tri 2)
  • B1 (indice de tri 3)
  • B2 (index de tri 3)
  • B3 (index de tri 3)

le comparateur sur eux prend la forme:

this.sortIndex.CompareTo(other.sortIndex) 

Quand je fais une list.sort() sur la liste des articles, je reçois l'ordre suivant sur:

  • A1
  • A2
  • B3
  • B2
  • B1

Il a évidemment travaillé dans le sens où les index de tri sont dans le bon commander, mais je ne veux vraiment pas qu'il soit en train de réorganiser les articles 'B'.

Y at-il un tweak je peux faire à mon comparateur pour résoudre ce problème?

+0

double possible de [Pourquoi la méthode Liste .Sort réordonner égale IComparable éléments?] (Http://stackoverflow.com/questions/800007/why-does-listt -sort-method-reorder-equal-icomparablet-elements) – nawfal

Répondre

5

OrderBy conserve l'ordre des articles égaux:

myList = myList.OrderBy(item => item.SortIndex).ToList(); 
5

vous devez utiliser un algorithme "stable sort" si vous ne voulez pas que les éléments qui sont égaux changent de position.

Consultez "merge sort" pour un exemple d'algorithme de tri stable. Voici an implementation en C#.

1

Vous pouvez changer votre comparateur pour faire un tri secondaire sur la valeur:

if (this.sortIndex.CompareTo(other.sortIndex) == 0) // same sortIndex 
{ 
    return this.Value.CompareTo(other.Value); 
} 
return 0; 
+0

Est-ce que ce n'est pas exactement la même chose que l'exemple que j'ai posté? –

+0

@Fiona: Non, le code utilise la valeur dans une comparaison secondaire, mais vous devez faire quelques corrections si vous voulez l'utiliser, car cela gâche la comparaison primaire en retournant zéro au lieu du résultat. – Guffa

+0

Ah je vois. Je n'ai pas de comparaison secondaire à utiliser vraiment (bien que je puisse ajouter un artificiel et cela fonctionnerait bien), l'ordre de liste que je veux préserver est basé sur la sortie d'une fonction récursive assez complexe. –

1

Trier utilise QuickSort, et il ne garantit pas d'origine séquence en cas d'égalité de comparaison.

Si vous voulez continuer à utiliser list.sort vous pouvez ajouter une seconde comparaison avec l'indice original comme:

int c = this.sortIndex.CompareTo(other.sortIndex); 
if (c == 0) 
    c = this.originalIndex.CompareTo(other.originalIndex); 
return c; 

sinon vous pouvez trier avec d'autres algorithmes « stables » (par exemple LINQ OrderBy).

2

StableSort() méthode d'extension pour List<T> est here

Questions connexes