2012-10-11 19 views
5

đang vật lộn với điều này trong một thời gian.Xóa tất cả các mục khỏi Danh sách <T> nếu các biến thể của T xảy ra

Tôi đang nhúng ngón chân vào thế giới WebAPI và tôi có Danh sách có thể chứa các sản phẩm có cùng tên nhưng giá khác nhau. Những gì tôi cần làm là xóa tất cả các tham chiếu vào sản phẩm là các biến thể về giá xảy ra.

ví dụ:
name = "cornflakes" Giá = "1.99M"
name = "cornflakes" Giá = "1.89M"
name = "Krispies Rice" Giá = "2.09M"
name = "cornflakes" Giá = " 2.09M "

Không có bột ngô sẽ xuất hiện trong danh sách cuối cùng của tôi.

Tôi đã viết hàng loạt nhưng đã xóa sản phẩm quá sớm và tôi không chắc chắn mình nên xóa chúng ở đâu.

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; 
    } 

Mọi trợ giúp sẽ được đánh giá cao.

Lưu ý: các loại ngũ cốc khác có sẵn

+0

@MarkByers Tôi chắc chắn rằng điều đó sẽ không bao giờ xảy ra. – Brett

Trả lời

2

Vui lòng thử này:

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; } 
     } 
    } 

Kết quả là bạn sẽ chỉ có một mục "Rice Krispies". Tôi chắc chắn nó sẽ làm việc nhanh hơn so với giải pháp với GroupBy và khác biệt, bởi vì chúng tôi không cần phải làm những điều không cần thiết trong trường hợp của bạn.

Mã hoạt động - http://ideone.com/X8A3v

12

Hãy thử biểu thức LINQ này sẽ chỉ chọn những sản phẩm có một giá riêng biệt:

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

Xem nó làm việc trực tuyến: ideone.

+0

Tuyệt vời! Cảm ơn vì điều đó, có vẻ như tôi cần chải lên LINQ nhiều hơn một chút. – Brett

1

Something như thế này (tự do như vậy có thể được cú pháp hơi sai):

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

này nên càng dễ dàng như nhóm theo tên, nhận chỉ những nơi chỉ có 1 mục tồn tại trong nhóm:

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

Sống dụ: http://rextester.com/AUBOHU96105

Các vấn đề liên quan