C# 根据条件从列表中删除重复项

C# 根据条件从列表中删除重复项,c#,linq,c#-4.0,C#,Linq,C# 4.0,我有一个带有属性(名称、价格)的类项目 我想删除项目,只有当名称存在不止一次,价格是500美元使用LINQ,而不创建自定义比较器?对于以上一项,带$500的1将从列表中删除 谢谢,查找重复项目可以通过以下方式完成: var dups = lst.Where(x=>lst.Any(y => y != x && y.Name == x.Name)) var dups500 = dups.Where(x=>x.Price == 500); 可以通过以下方式查找价格

我有一个带有属性(名称、价格)的类项目

我想删除项目,只有当名称存在不止一次,价格是500美元使用LINQ,而不创建自定义比较器?对于以上一项,带$500的1将从列表中删除


谢谢,

查找重复项目可以通过以下方式完成:

var dups = lst.Where(x=>lst.Any(y => y != x && y.Name == x.Name))
var dups500 = dups.Where(x=>x.Price == 500);
可以通过以下方式查找价格
500
的重复项目:

var dups = lst.Where(x=>lst.Any(y => y != x && y.Name == x.Name))
var dups500 = dups.Where(x=>x.Price == 500);
最后,可以使用EXPECT方法删除dups500:

var result = lst.Except(dup);
或一应俱全:

var result = 
     lst.Except(
               lst
               .Where(x=>x.Price == 500 && 
                         lst.Any(y => y != x && y.Name == x.Name))).ToList();
//这里有指定条件的项目列表。从基础集合中删除它们

尝试以下操作:

var result = items
    .GroupBy(item => item.Name)
    .SelectMany(g => g.Count() > 1 ? g.Where(x => x.Price != 500) : g);
第一组的名字。如果组中有多个项目,请仅从价格不为500的组中选择项目。

我将首先创建一个包含重复项的预评估子集列表:

var result =
    from item in items
    where item.Price != 500 || items.Count(i => i.Name == item.Name) == 1
    select item;
var dupes = list.Where(a => list.Count(b => b.Name.Equals(a.Name)) > 1).ToList();
.ToList()
确保此查询只计算一次。如果列表很大,这将在速度上产生巨大的差异

现在,如果您的列表是
列表
,则可以使用
RemoveAll()
方法:

list.RemoveAll(item => item.Price == 500 && dupes.Contains(item));
你完成了

但是,如果您的列表只有
IEnumerable
,或者您不想修改源列表,或者您想要延迟执行,那么只需使用LINQ:

var result = list.Where(item => !(item.Price == 500 && dupes.Contains(item)));
这将在枚举
结果时进行计算

我想删除项目只有当名称存在不止一次,价格是500美元

var Test=(来自DataTable.AsEnumerable()中的行)
选择row.Field(“ColumnName”).Distinct();

@KirkWoll,这取决于你的口味,但并不令人困惑:
除外
表示
除外
,而内部
搜索具有给定条件的项目似乎很简单:)但这取决于你的选择。(这也比groupby one快)。这并不能同时保持两者的一致性Item3s@MartinNeal,我不明白你的意思?@Saeed:
除了
返回两个序列的“集差”(即,它排除重复项)。由于OP的示例中有两个项目带有
{Name=“Item3”,Price=$150}
,因此这些项目中的一个可能会被
排除在外,除了
(例如,如果它们是相同的对象;或者如果它们具有将它们视为相等的
Equals
方法;或者如果您使用将它们视为相等的
IEqualityComparer
)。但是,如果它们不被认为是相等的,并且它们只是两个碰巧具有相同名称和价格的对象,那么您就没事了。嗯,这取决于OP对其Item类的定义。我使用匿名类进行了测试,y!=x部分的行为不同。这将删除价格为500的项目,即使它不是重复的。1准备好这些好东西。
Apple 300 <-- winner
Apple 500 <-- dupe
Banana 500  <-- winner
Banana 500  <-- dupe
Banana 500  <-- dupe
Cantelope 100 <-- winner
Cantelope 200 <-- winner
from item in source
group item by item.Name into g
let okItems = g.Where(x => x.Price != 500)
let secondChoiceItem = g.FirstOrDefault(x => x.Price == 500)
let theItems = okItems.DefaultIfEmpty(secondChoiceItem)
from nonDupeItem in theItems
select nonDupeItem
var Test = (from row in DataTable.AsEnumerable()
            select row.Field<string>("ColumnName")).Distinct();