Parfois, vous n'avez pas le luxe de l'indexation, ou peut-être voulez-vous inverser les résultats d'une requête Linq, ou peut-être que vous ne voulez pas modifier la collection source, si l'un de ces éléments est vrai, Linq peut vous aider.
Une méthode d'extension Linq utilisant des types anonymes avec Linq Select pour fournir une clé de tri pour Linq OrderByDescending;
public static IEnumerable<T> Invert<T>(this IEnumerable<T> source)
{
var transform = source.Select(
(o, i) => new
{
Index = i,
Object = o
});
return transform.OrderByDescending(o => o.Index)
.Select(o => o.Object);
}
Usage:
var eable = new[]{ "a", "b", "c" };
foreach(var o in eable.Invert())
{
Console.WriteLine(o);
}
// "c", "b", "a"
Il est nommé "Invert" car il est synonyme de "Reverse" et permet de lever l'ambiguïté avec l'implémentation List Reverse.
Il est également possible d'inverser certaines plages d'une collection, puisque Int32.MinValue et Int32.MaxValue sont hors de la plage de tout type d'index de collection, nous pouvons les exploiter pour le processus de commande; si un index d'élément est inférieur à la plage donnée, il est affecté Int32.MaxValue afin que son ordre ne change pas lors de l'utilisation de OrderByDescending, de même, les éléments à un index supérieur à la plage donnée, seront affectés Int32.MinValue, de sorte qu'ils apparaissent à la fin du processus de commande. Tous les éléments de la plage donnée reçoivent leur index normal et sont inversés en conséquence.
public static IEnumerable<T> Invert<T>(this IEnumerable<T> source, int index, int count)
{
var transform = source.Select(
(o, i) => new
{
Index = i < index ? Int32.MaxValue : i >= index + count ? Int32.MinValue : i,
Object = o
});
return transform.OrderByDescending(o => o.Index)
.Select(o => o.Object);
}
Usage:
var eable = new[]{ "a", "b", "c", "d" };
foreach(var o in eable.Invert(1, 2))
{
Console.WriteLine(o);
}
// "a", "c", "b", "d"
Je ne suis pas sûr des performances de ces implémentations Linq par rapport à l'utilisation d'une liste temporaire pour envelopper une collection pour l'inversion.
Au moment de la rédaction de cet article, je n'étais pas au courant de la propre implémentation inverse de Linq, mais c'était amusant de résoudre ce problème.
https://msdn.microsoft.com/en-us/library/vstudio/bb358497(v=vs.100).aspx