92 votes

comment supprimer les chaînes vides d'une liste, puis supprimer les valeurs dupliquées d'une liste

Disons que j'ai une liste de valeurs de colonnes provenant d'une table, comment supprimer les chaînes vides et les valeurs dupliquées. Voir le code suivant :

List<string> dtList = dtReportsList.AsEnumerable().Select(dr => dr.Field<string>("column1")).ToList();

C'est ce que j'ai codé à l'instant mais le code d'Amiram est bien plus élégant, je vais donc choisir cette réponse voici comment je l'ai fait :

DataTable dtReportsList = someclass.GetReportsList();

        if (dtReportsList.Rows.Count > 0)
       { 
           List<string> dtList = dtReportsList.AsEnumerable().Select(dr => dr.Field<string>("column1")).ToList();
           dtList.RemoveAll(x=>x == "");
           dtList = dtList.Distinct().ToList();         

           rcboModule.DataSource = dtList;
           rcboModule.DataBind();               
           rcboModule.Items.Insert(0, new RadComboBoxItem("All", "All"));
       }

241voto

Amiram Korach Points 7101
dtList = dtList.Where(s => !string.IsNullOrWhiteSpace(s)).Distinct().ToList();

J'ai supposé que les chaînes vides et les espaces blancs sont comme null. Si ce n'est pas le cas, vous pouvez utiliser IsNullOrEmpty (autoriser les espaces), ou s != null

11voto

Bojan Points 121

Pour simplifier Amiram Korach solution :

dtList.RemoveAll(s => string.IsNullOrWhiteSpace(s))

Il n'est pas nécessaire d'utiliser Distinct() ou ToList()

10voto

KeithS Points 36130

La réponse d'Amiram est correcte, mais Distinct() tel qu'il est implémenté est un N 2 Pour chaque élément de la liste, l'algorithme le compare à tous les éléments déjà traités et le renvoie s'il est unique ou l'ignore dans le cas contraire. Nous pouvons faire mieux.

A trié peut être dédupliquée en temps linéaire ; si l'élément courant est égal à l'élément précédent, il est ignoré, sinon il est retourné. Le tri est NlogN, donc même en triant la collection, on obtient un certain bénéfice :

public static IEnumerable<T> SortAndDedupe<T>(this IEnumerable<T> input)
{
   var toDedupe = input.OrderBy(x=>x);

   T prev;
   foreach(var element in toDedupe)
   {
      if(element == prev) continue;

      yield return element;
      prev = element;      
   }
}

//Usage
dtList  = dtList.Where(s => !string.IsNullOrWhitespace(s)).SortAndDedupe().ToList();

Cette fonction renvoie les mêmes éléments ; ils sont simplement triés.

3voto

IneedHelp Points 632

La solution d'Amiram Korach est en effet bien ordonnée. Voici une alternative pour plus de polyvalence.

var count = dtList.Count;
// Perform a reverse tracking.
for (var i = count - 1; i > -1; i--)
{
    if (dtList[i]==string.Empty) dtList.RemoveAt(i);
}
// Keep only the unique list items.
dtList = dtList.Distinct().ToList();

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