91 votes

Comment trier un IEnumerable<string>

Comment puis-je trier un IEnumerable par ordre alphabétique. Est-ce possible?

Modifier: Comment écrirais-je une solution sur place?

145voto

dtb Points 104373

De la même manière que vous trieriez n'importe quel autre énumérable :

var result = myEnumerable.OrderBy(s => s);

ou

var result = from s in myEnumerable
             orderby s
             select s;

ou (en ignorant la casse)

var result = myEnumerable.OrderBy(s => s,
                                  StringComparer.CurrentCultureIgnoreCase);

Notez que, comme c'est habituel avec LINQ, cela crée un nouveau IEnumerable qui, lorsqu'il est énuméré, renvoie les éléments de l'original IEnumerable dans l'ordre trié. Cela ne trie pas l'IEnumerable sur place.


Un IEnumerable est en lecture seule, c'est-à-dire que vous ne pouvez récupérer que les éléments, mais ne pouvez pas le modifier directement. Si vous voulez trier une collection de chaînes sur place, vous devez trier la collection d'origine qui implémente IEnumerable, ou transformer d'abord un IEnumerable en une collection sortable :

List myList = myEnumerable.ToList();
myList.Sort();

Basé sur votre commentaire :

_components = (from c in xml.Descendants("component")
               let value = (string)c
               orderby value
               select value
              )
              .Distinct()
              .ToList();

ou

_components = xml.Descendants("component")
                 .Select(c => (string)c)
                 .Distinct()
                 .OrderBy(v => v)
                 .ToList();

ou (si vous voulez ajouter plus d'éléments à la liste plus tard et la garder triée)

_components = xml.Descendants("component")
                 .Select(c => (string)c)
                 .Distinct()
                 .ToList();

_components.Add("foo");
_components.Sort();

10voto

James Curran Points 55356

Il est impossible, mais ce n'est pas le cas.

Fondamentalement, toute méthode de tri va copier votre IEnumerable dans une liste List, trier la liste et ensuite vous retourner la liste triée, qui est à la fois un IEnumerable ainsi qu'une IList.

Cela signifie que vous perdez la propriété de "continuer indéfiniment" d'un IEnumerable, mais de toute façon vous ne pourriez pas trier un comme ça de toute façon.

8voto

Larsenal Points 17080
myEnumerable = myEnumerable.OrderBy(s => s);

2voto

Jon Hanna Points 40291

Nous ne pouvons pas toujours le faire sur place, mais nous détectons quand c'est possible :

IEnumerable SortInPlaceIfCan(IEnumerable src, IComparer cmp)
{
  List listToSort = (src is List) ? (List)src : new List(src);
  listToSort.Sort(cmp);
  return listToSort;
}
IEnumerable SortInPlaceIfCan(IEnumerable src, Comparison cmp)
{
  return SortInPlaceIfCan(src, new FuncComparer(cmp));
}
IEnumerable SortInPlaceIfCan(IEnumerable src)
{
  return SortInPlaceIfCan(src, Comparer.Default);
}

Cela utilise la structure pratique suivante :

internal struct FuncComparer : IComparer
{
  private readonly Comparison _cmp;
  public FuncComparer(Comparison cmp)
  {
      _cmp = cmp;
  }
  public int Compare(T x, T y)
  {
      return _cmp(x, y);
  }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X