2010-01-24 15 views
8

Tengo una clase llamada Item. El artículo tiene una propiedad de identificador llamada ItemCode que es una cadena. Me gustaría obtener una lista de todos los elementos no diferenciados en una lista de artículos.Obtener elementos no distintivos de un IEnumerable

Ejemplo:

List<Item> itemList = new List<Item>() 
{ 
    new Item("code1", "description1"), 
    new Item("code2", "description2"), 
    new Item("code2", "description3"), 
}; 

Quiero una lista que contiene las dos últimas entradas

Si uso

var distinctItems = itemsList.Distinct(); 

tengo la lista de elementos distintos que es grande, pero quiero casi lo opuesto a eso. Podría restar la lista distinta de la lista original pero eso no contendría TODAS las repeticiones, solo una instancia de cada una.

He tenido una jugada y no puedo encontrar una solución elegante. Cualquier puntero o ayuda sería muy apreciada. ¡Gracias!

tengo 3.5 por lo LINQ está disponible

Respuesta

11

Mi opinión:

var distinctItems = 
    from list in itemsList 
    group list by list.ItemCode into grouped 
    where grouped.Count() > 1 
    select grouped; 
+0

Gracias Magnus (y Thomas) y no pensé en usar GroupBy – RichK

2

Es posible que desee probarlo con el grupo por el operador. La idea sería la de agruparlos por el ItemCode y teniendo los grupos con más de un miembro, algo así como:

var grouped = from i in itemList 
       group i by i.ItemCode into g 
       select new { Code = g.Key, Items = g }; 

var result = from g in grouped 
      where g.Items.Count() > 1; 
+0

No puedo conseguir esto para compilar. Gime sobre las declaraciones 'group by' y 'into' – RichK

+0

Olvidé la "i" entre group y by: $ Ahora está arreglada, pero es esencialmente lo mismo que magnus wrote. –

0

yo sugiero escribir un método de extensión personalizada, algo como esto:

static class RepeatedExtension 
{ 
    public static IEnumerable<T> Repeated<T>(this IEnumerable<T> source) 
    { 
     var distinct = new Dictionary<T, int>(); 
     foreach (var item in source) 
     { 
      if (!distinct.ContainsKey(item)) 
       distinct.Add(item, 1); 
      else 
      { 
       if (distinct[item]++ == 1) // only yield items on first repeated occurence 
        yield return item; 
      }      
     } 
    } 
} 

también es necesario reemplazar el método equals() para su clase de artículos, por lo que los artículos se comparan correctamente por su código.

11

como un método de extensión:

public static IEnumerable<T> NonDistinct<T, TKey> (this IEnumerable<T> source, Func<T, TKey> keySelector) 
{ 
    return source.GroupBy(keySelector).Where(g => g.Count() > 1).SelectMany(r => r); 
} 
+0

Limpio y muy reutilizable, gracias! – crabCRUSHERclamCOLLECTOR

Cuestiones relacionadas