C # Trier la liste tout en renvoyant les positions d’index d’origine?

Je souhaite sortinger une collection, mais aussi renvoyer un index qui peut être utilisé pour mapper la position d’origine dans la collection (avant le sorting).

Permettez-moi de donner un exemple pour être plus clair:

List A = new List(){3,2,1}; List B; List idx; Sort(A,out B,out idx); 

Après quoi:

 A = [3,2,1] B = [1,2,3] idx = [2,1,0] 

Pour que la relation entre A, B, idx soit:

A[i] == B[ idx[i] ] , pour i = 0 … 2

C # /. Net a-t-il un mécanisme intégré pour rendre cela facile à implémenter?

Merci.

Cela peut être fait assez facilement avec Linq.

  • Convertissez votre liste en une nouvelle liste de paires (object, index d’origine de l’object).
  • Trier la nouvelle liste par le premier élément de la paire
  • Extrayez la liste sortingée et les index d’origine.

Voici un code pour démontrer le principe:

 List A = new List() { 3, 2, 1 }; var sorted = A .Select((x, i) => new KeyValuePair(x, i)) .OrderBy(x => x.Key) .ToList(); List B = sorted.Select(x => x.Key).ToList(); List idx = sorted.Select(x => x.Value).ToList(); 

Je pense que cela donne A [idx [i]] = B [i], mais cela devrait suffire pour vous.

Alors que Mark Byers vous a fourni une solution à l’ aide de LINQ, je souhaite vous montrer une autre solution à l’aide de .NET Framework.

Il y a une surcharge de Array.Sort qui fera ceci pour vous:

 int[] a = new[] { 3, 2, 1 }; int[] p = new[] { 0, 1, 2 }; Array.Sort(a, p); Assert.IsTrue(a.SequenceEquals(new[] { 1, 2, 3 })); Assert.IsTrue(p.SequenceEquals(new[] { 2, 1, 0 })); 

Ainsi, voici une méthode générique qui répond à vos spécifications et qui exploite cette surcharge:

 void Sort( List input, out List output, out List permutation, IComparer comparer ) { if(input == null) { throw new ArgumentNullException("input"); } if(input.Count == 0) { // give back empty lists output = new List(); permutation = new List(); return; } if(comparer == null) { throw new ArgumentNullException("comparer"); } int[] items = Enumerable.Range(0, input.Count).ToArray(); T[] keys = input.ToArray(); Array.Sort(keys, items, comparer); output = keys.ToList(); permutation = items.ToList(); } 

une approche plus élégante en utilisant lambda

 Array.Sort(idx, (a, b) => A[a].CompareTo(A[b])); 

cela donne u tableau idx du tableau A