2012-10-11 21 views
5

ha estado luchando con esto por un tiempo.Eliminar todos los elementos de una lista <T> si ocurren variaciones de T

Estoy sumergiendo mi dedo del pie en el mundo de WebAPI y tengo una lista que puede contener productos con el mismo nombre pero precios diferentes. Lo que tengo que hacer es eliminar todas las referencias a un producto son variaciones en el precio.

por ejemplo.
name = "Corn Flakes" Precio = "1,99 metros"
name = "Corn Flakes" Precio = "1.89M"
name = "Rice Krispies" Precio = "2.09M"
name = "Corn Flakes" Precio = " 2.09M "

No cornflakes debería aparecer en mi lista final.

Tengo el grueso escrito pero está retirando los productos demasiado pronto y no estoy seguro de dónde debería eliminarlos.

public IEnumerable<Product> GetProductsByCategory(int Id) 
    { 
     List<Product> sourceProductList = products.Where(p => p.CategoryID == Id).ToList(); 
     List<Product> tempProducts = new List<Product>(); 
     List<Product> targetProductList = new List<Product>(); 

     foreach (var product in sourceProductList) 
     { 
      bool isInTempList = tempProducts.Any(x => x.Name == product.Name); 
      if (!isInTempList) 
      { 
       tempProducts.Add(product); 
      } 
      else 
      { 
       Product tempProduct = product; 
       bool isPriceDifferent = tempProducts.Where(y => y.Name == tempProduct.Name).Any(y => y.Price != tempProduct.Price); 
       if (isPriceDifferent) 
       { 
        tempProducts.RemoveAll(p => p.Name == product.Name); 
        // too soon as I may have lots of products with the same name 
        // but need to remove based on product.Name 
       } 
      } 
     } 
     targetProductList.AddRange(tempProducts); 

     return targetProductList; 
    } 

Cualquier ayuda sería muy apreciada.

Nota: otros cereales están disponibles

+0

@MarkByers me han asegurado que nunca va a suceder. – Brett

Respuesta

2

Por favor, intente esto:

class Program 
    { 
     static void Main(string[] args) 
     { 
      var list = new List<Product> 
       { 
        new Product() {Name = "Cornflakes", Price = 100}, 
        new Product() {Name = "Cornflakes", Price = 200}, 
        new Product() {Name = "Rice Krispies", Price = 300}, 
        new Product() {Name = "Cornflakes", Price = 400} 
       }; 

      var uniqueItems = list.Where(w => (!list.Any(l=>l.Name.Equals(w.Name) && l != w))); 

     } 

     public class Product 
     { 

      public string Name { get; set; } 
      public decimal Price { get; set; } 
     } 
    } 

En el resultado, tendrá solo un artículo "Rice Krispies". Estoy seguro de que funcionará más rápido que la solución con GroupBy y Distinct, porque no necesitamos hacer estas cosas innecesarias en su caso.

Código de Trabajo - http://ideone.com/X8A3v

12

Pruebe esta expresión LINQ que sólo seleccionar los productos que tienen un precio distinto:

var result = sourceProductList 
    .GroupBy(x => x.Name) 
    .Where(g => g.Select(x => x.Price).Distinct().Count() == 1) 
    .Select(g => g.First()); 

ver su funcionamiento en línea: ideone.

+0

¡Impresionante! Gracias por eso, parece que necesito repasar un poco más mi LINQ. – Brett

1

Algo como esto (a mano alzada por lo que puede ser la sintaxis un poco mal):

var toRemove = sourceProductList 
    .GroupBy(p => p.Name) 
    .Where(g => g.Count() > 1) 
    .SelectMany(g => g) 
    .GroupBy(p => p.Price) 
    .Where(g => g.Count() > 1) 
    .SelectMany(g => g.Select(p => p.ID)) 
    .Distinct() 
    .ToList(); 
toRemove.ForEach(id => sourceProductList.RemoveAll(p => p.ID == id)); 
1

Esto debería ser tan fácil como agrupación por su nombre, recibiendo sólo aquellos en los que existe sólo 1 punto en los grupos:

var filtered = list.GroupBy(i => i.Name) 
     .Where(i => i.Count() == 1) 
     .SelectMany(x => x) 

vivo ejemplo: http://rextester.com/AUBOHU96105

Cuestiones relacionadas