如果 T 发生变化,则从 List<T> 中删除所有项目
Posted
技术标签:
【中文标题】如果 T 发生变化,则从 List<T> 中删除所有项目【英文标题】:Remove all items from a List<T> if variations of T occur 【发布时间】:2012-10-02 04:02:35 【问题描述】:已经为此苦苦挣扎了一段时间。
我正在涉足 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 我确信这永远不会发生。 【参考方案1】:试试这个 LINQ 表达式,它只会选择具有不同价格的产品:
var result = sourceProductList
.GroupBy(x => x.Name)
.Where(g => g.Select(x => x.Price).Distinct().Count() == 1)
.Select(g => g.First());
在线查看:ideone。
【讨论】:
太棒了!谢谢你,看来我需要再学习一下我的 LINQ。【参考方案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
【讨论】:
【参考方案3】:类似这样的东西(写意所以可能语法稍有错误):
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));
【讨论】:
【参考方案4】:这应该像按名称分组一样简单,只获取组中仅存在 1 个项目的那些:
var filtered = list.GroupBy(i => i.Name)
.Where(i => i.Count() == 1)
.SelectMany(x => x)
现场示例:http://rextester.com/AUBOHU96105
【讨论】:
以上是关于如果 T 发生变化,则从 List<T> 中删除所有项目的主要内容,如果未能解决你的问题,请参考以下文章
如果数组值包含字符串,则从 List<string> 中查找值 [重复]