C# LINQ Except/Distinct仅基于少数列,不添加重复项
请原谅我把标题弄糊涂了。但我想不出更简单的办法 我的功课不及格C# LINQ Except/Distinct仅基于少数列,不添加重复项,c#,.net,linq,distinct,except,C#,.net,Linq,Distinct,Except,请原谅我把标题弄糊涂了。但我想不出更简单的办法 我的功课不及格 public class Foo { public FooId int { get; set; } public FooField string { get; set; } //some more fields here.... //.... //.... public DateTime CreatedDate { get; set; } } 我需要循环一些内容,并将一系列的F
public class Foo
{
public FooId int { get; set; }
public FooField string { get; set; }
//some more fields here....
//....
//....
public DateTime CreatedDate { get; set; }
}
我需要循环一些内容,并将一系列的Foo
添加到列表中,但基于FooId
和FooField
的组合,它不应该重复
所以我尝试如下
List<Foo> foos = new List<Foo>();
foreach (Bar item in blah.Bars)
{
//Some code here to get the foos from the item
List<Foo> processedFoos = item.GetFoos();
//The problem is with below line
foos.AddRange(processedFoos.Except(foos));
}
List foos=new List();
foreach(条形图中的条形图项目)
{
//这里有一些代码可以从项目中获取foos
List processedFoos=item.GetFoos();
//问题出在底线以下
foos.AddRange(processedFoos.Except(foos));
}
Except
添加所有记录并复制FooId
和FooField
组合,因为CreatedDate
对于所有记录都是唯一的
但是我需要忽略CreatedDate
,只添加那些不违反唯一组合的记录
我能在这里做什么<代码>除了
<代码>不同的?还有其他选择吗
最重要的是,如何比较?除了之外的
和不同的
都将基于对象的等于
实现来比较项目(这是默认的相等比较器)。它们还都有重载,这些重载采用IEqualityComparer
您可以实现此接口(请参见示例),只比较所需的字段,并将其传递给除
之外的:
foos.AddRange(processedFoos.Except(foos, comparer));
Except
和Distinct
都将基于对象的Equals
实现来比较项目(这是默认的相等比较器)。它们还都有重载,这些重载采用IEqualityComparer
您可以实现此接口(请参见示例),只比较所需的字段,并将其传递给除
之外的:
foos.AddRange(processedFoos.Except(foos, comparer));
您需要覆盖Foo
中的Equals
,或者实现IEqualityComparer
,以便Except
可以判断两个Foo
值何时相等。例如:
public sealed class FooComparer : IEqualityComparer<Foo>
{
public bool Equals(Foo x, Foo y)
{
return x.FooId == y.FooId && x.FooField == y.FooField;
}
public int GetHashCode(Foo foo)
{
// Note that if FooField can be null, you'll need to account for that...
return foo.FooId ^ foo.FooField.GetHashCode();
}
}
您需要覆盖Foo
中的Equals
,或者实现IEqualityComparer
,以便Except
可以判断两个Foo
值何时相等。例如:
public sealed class FooComparer : IEqualityComparer<Foo>
{
public bool Equals(Foo x, Foo y)
{
return x.FooId == y.FooId && x.FooField == y.FooField;
}
public int GetHashCode(Foo foo)
{
// Note that if FooField can be null, you'll need to account for that...
return foo.FooId ^ foo.FooField.GetHashCode();
}
}
我认为您应该改变选择不重复记录的方式:
processedFoos.Where(x => !foos.Any(y => y.FooId == x.FooId && y.FooField == x.FooField))
我认为您应该改变选择不重复记录的方式:
processedFoos.Where(x => !foos.Any(y => y.FooId == x.FooId && y.FooField == x.FooField))
Except
和Distinct
都有一个重载,需要IEqualityComparer
。您可以实现一个来只比较所需的属性
另一种方法是按FooId和FooField分组,并从每个组中获取第一个元素:
processFoos.GroupBy(foo => new {foo.FooId, foo.FooField})
.Select(g => g.First());
Except
和Distinct
都有一个重载,需要IEqualityComparer
。您可以实现一个来只比较所需的属性
另一种方法是按FooId和FooField分组,并从每个组中获取第一个元素:
processFoos.GroupBy(foo => new {foo.FooId, foo.FooField})
.Select(g => g.First());
实现IEqualityComparer
并使用Except()
的适当重载实现IEqualityComparer
并使用Except()
方法很好,但基于唯一的组合,它会得到不同的processedFoos
。我需要检查processedFoos
中是否存在重复的foos
。谢谢你的回答。谢谢!我将实现IEqualityComparer
,正如您和其他人所建议的,@Jon Skeet在他的回答中所演示的那样。GroupBy().Select()
方法很好,但它会根据独特的组合得到不同的processedFoos
。我需要检查processedFoos
中是否存在重复的foos
。谢谢你的回答。谢谢!我将实施IEqualityComparer
,正如您和其他人所建议的,@Jon Skeet在他的回答中所展示的那样。