如果T的变体出现,从List<T>中删除所有项目

5

我已经苦恼了一段时间。

我正在涉足WebAPI领域,我有一个列表,其中包含名称相同但价格不同的产品。我需要做的是在价格变化时删除产品的所有引用。

例如:
名称=“玉米片” 价格=“1.99M”
名称=“玉米片” 价格=“1.89M”
名称=“Rice Krispies” 价格=“2.09M”
名称=“玉米片” 价格=“2.09M”

没有 玉米片应该出现在我的最终列表中。

我已经写好了大部分内容,但是它们删除产品的时间过早,我不确定应该在哪里删除它们。

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

任何帮助都将不胜感激。
注意:还有其他谷物可供选择。

@MarkByers 我已经得到保证,这种情况永远不会发生。 - Brett
4个回答

12

尝试使用此LINQ表达式,它只会选择具有一个独特价格的产品:

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

在线查看示例:ideone


太棒了!谢谢你,看来我需要更加熟悉LINQ。 - Brett

2
请尝试这个:
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; }
        }
    }

结果中只会有一个“Rice Krispies”项目。我相信这比使用GroupBy和Distinct的解决方案更快,因为在您的情况下我们不需要做这些不必要的事情。
工作代码- http://ideone.com/X8A3v

1

类似这样的东西(手写可能语法有些错误):

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
这应该很容易,只需按名称分组,获取仅在组中存在1个项目的那些项目即可:
var filtered = list.GroupBy(i => i.Name)
      .Where(i => i.Count() == 1)
      .SelectMany(x => x)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接