2011-12-16 12 views
7

Tengo una lista de objetos que algunos de ellos tienen el mismo ID, así que me gustaría para eliminar aquellos elementos que se duplican.distintas en el marco Entidad

me trataron con algo como esto:

List<post> posts = postsFromDatabase.Distinct().ToList(); 

Pero esto no funciona!

Así que escribió este método a fin de evitar los duplicados:

public List<Post> PostWithOutDuplicates(List<Post> posts) 
    { 
     List<Post> postWithOutInclude = new List<Post>(); 
     var noDupes = posts.Select(x => x.Id).Distinct(); 
     if (noDupes.Count() < posts.Count) 
     { 
      foreach (int idPost in noDupes) 
      { 
       postWithOutInclude.Add(posts.Where(x => x.Id == idPost).First()); 
      } 
      return postWithOutInclude; 
     } 
     else 
     { 
      return posts; 
     } 
    } 

todas las ideas de cómo mejorar el rendimiento ??

Gracias de antemano.

+0

¿Cómo es que tiene ID duplicados? Parece un problema más grande de abordar. – Mikeb

Respuesta

25

Ésta es agradable y fácil:

List<Post> posts = posts 
.GroupBy(x => x.Id) 
.Select(x => x.FirstOrDefault()) 

Pero si desea escribir de la manera correcta, me gustaría aconsejarle a escribir así:

public class PostComparer : IEqualityComparer<Post> 
{ 
    #region IEqualityComparer<Post> Members 

    public bool Equals(Post x, Post y) 
    { 
     return x.Id.Equals(y.Id); 
    } 

    public int GetHashCode(Post obj) 
    { 
     return obj.Id.GetHashCode(); 
    } 

    #endregion 
} 

ya que le dará tienes más libertad cuando se trata de comparaciones adicionales. Después de haber escrito esta clase, puede usarla así:

List<Post> posts = postsFromDatabase.Distinct(new PostComparer()).ToList(); 
+2

creo en 'GetHashCode' debe utilizar' obj.Id.GetHashCode() 'debido a que el código hash debe ser el mismo para los dos objetos que son iguales de acuerdo con el método' Equals' (al menos MSDN dice esto). – Slauma

+0

¡Bien visto! Debería haber Id.GetHashCode(), tienes razón. Si alguien está interesado: http://msdn.microsoft.com/en-us/library/ms132151.aspx –

+3

Esto manejar esto cuando los datos están en la memoria. No está bien. Utilice el GroupBy-approch: http://stackoverflow.com/questions/8560884/how-to-implement-iequalitycomparer-to-return-distinct-values ​​ –

1

en lugar de .First(), tratan .FirstOrDefault()

5

Creo que escribe su propio comparador personalizado es un buen enfoque.

Aquí es un artículo de MSDN que explica el tema muy bien: http://support.microsoft.com/kb/320727

La razón por la que la Distinto no su funcionamiento que Distinct() no tiene idea acerca de cómo detemine si hay iguales, por lo que es el uso la referencia para determinarlo es el mismo "objeto". Está funcionando como si se suponía que funcionara. Todas las clases en la consulta no son el mismo objeto.

Al escribir su propio comparador (es fácil) se puede decir que Distinct() cómo hacer la comparacion para determinar si son iguales.

Editar: Si no se usa Distinct no es un problema y la situación no es frecuente, la primera respuesta de Piotr Justyna es simple y efectiva.

+0

Sugiero usar un GroupBy() si es posible. –

Cuestiones relacionadas