[c#] Eliminar duplicados de una lista <T> en C #



Answers

Si usa .Net 3+, puede usar Linq.

List<T> withDupes = LoadSomeData();
List<T> noDupes = withDupes.Distinct().ToList();
Question

¿Alguien tiene un método rápido para quitar la duplicación de una lista genérica en C #?




Sería más fácil simplemente asegurarse de que los duplicados no se agreguen a la lista.

if(items.IndexOf(new_item) < 0) 
    items.add(new_item)



Otra forma en .Net 2.0

    static void Main(string[] args)
    {
        List<string> alpha = new List<string>();

        for(char a = 'a'; a <= 'd'; a++)
        {
            alpha.Add(a.ToString());
            alpha.Add(a.ToString());
        }

        Console.WriteLine("Data :");
        alpha.ForEach(delegate(string t) { Console.WriteLine(t); });

        alpha.ForEach(delegate (string v)
                          {
                              if (alpha.FindAll(delegate(string t) { return t == v; }).Count > 1)
                                  alpha.Remove(v);
                          });

        Console.WriteLine("Unique Result :");
        alpha.ForEach(delegate(string t) { Console.WriteLine(t);});
        Console.ReadKey();
    }



Simplemente inicialice un HashSet con una Lista del mismo tipo:

var noDupes = new HashSet<T>(withDupes);

O, si desea que se devuelva una lista:

var noDupsList = new HashSet<T>(withDupes).ToList();



La respuesta de David J. es un buen método, sin necesidad de objetos adicionales, clasificación, etc. Sin embargo, se puede mejorar:

for (int innerIndex = items.Count - 1; innerIndex > outerIndex ; innerIndex--)

Entonces, el bucle externo va a la parte superior superior de toda la lista, pero el bucle interno va hacia la parte inferior "hasta que se alcanza la posición de bucle externo".

El bucle externo asegura que se procesa toda la lista, el bucle interno encuentra los duplicados reales, que solo pueden suceder en la parte que el bucle externo no ha procesado aún.

O si no desea hacer la parte inferior para el ciclo interno, puede hacer que el ciclo interno comience en outerIndex + 1.




Si no le importa el pedido, puede meter los artículos en un HashSet , si desea mantener el orden, puede hacer algo como esto:

var unique = new List<T>();
var hs = new HashSet<T>();
foreach (T t in list)
    if (hs.Add(t))
        unique.Add(t);

O la forma de Linq:

var hs = new HashSet<T>();
list.All( x =>  hs.Add(x) );

Editar: El método HashSet es O(N) tiempo y O(N) espacio mientras ordena y hace único (como lo sugieren @ lassevk y otros) es O(N*lgN) tiempo y O(1) espacio así que no es así claro para mí (como lo fue a primera vista) que el camino de clasificación es inferior (mis disculpas por el voto de baja temporal ...)




Me gusta usar este comando:

List<Store> myStoreList = Service.GetStoreListbyProvince(provinceId)
                                                 .GroupBy(s => s.City)
                                                 .Select(grp => grp.FirstOrDefault())
                                                 .OrderBy(s => s.City)
                                                 .ToList();

Tengo estos campos en mi lista: Id, StoreName, City, PostalCode. Quería mostrar la lista de ciudades en un menú desplegable que tiene valores duplicados. Solución: Agrupe por ciudad y elija el primero para la lista.

Espero que ayude :)




En Java (supongo que C # es más o menos idéntico):

list = new ArrayList<T>(new HashSet<T>(list))

Si realmente deseaba mutar la lista original:

List<T> noDupes = new ArrayList<T>(new HashSet<T>(list));
list.clear();
list.addAll(noDupes);

Para preservar el orden, simplemente reemplace HashSet con LinkedHashSet.




Puedes usar Union

obj2 = obj1.Union(obj1).ToList();



Instalando el paquete MoreLINQ través de Nuget, puede fácilmente distinguir la lista de objetos por una propiedad

IEnumerable<Catalogue> distinctCatalogues = catalogues.DistinctBy(c => c.CatalogueCode); 



Funcionó para mí simplemente use

List<Type> liIDs = liIDs.Distinct().ToList<Type>();

Reemplace "Tipo" con el tipo deseado, por ejemplo, int.






Related



Tags

c# c#   generics