C# Linq 与对象的一部分相交/除外
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10633375/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C# Linq intersect/except with one part of object
提问by David Archer
I've got a class:
我有一堂课:
class ThisClass
{
private string a {get; set;}
private string b {get; set;}
}
I would like to use the Intersect and Except methods of Linq, i.e.:
我想使用 Linq 的 Intersect 和 except 方法,即:
private List<ThisClass> foo = new List<ThisClass>();
private List<ThisClass> bar = new List<ThisClass>();
Then I fill the two lists separately. I'd like to do, for example (and I know this isn't right, just pseudo code), the following:
然后我分别填写这两个列表。例如,我想做(我知道这是不对的,只是伪代码),如下:
foo[a].Intersect(bar[a]);
How would I do this?
我该怎么做?
采纳答案by Sergey Berezovskiy
Maybe
也许
// returns list of intersecting property 'a' values
foo.Select(f => f.a).Intersect(bar.Select(b => b.a));
BTW property ashould be public.
顺便说一句,财产a应该是公开的。
回答by Tilak
foo.Select(x=>x.a).Intersect(bar.Select(x=>x.a))
回答by Patryk ?wiek
If you want a list of a single property you'd like to intersect then all the other pretty LINQ solutions work just fine.
BUT! If you'd like to intersect on a whole class though and as a result have a List<ThisClass>instead of List<string>you'll have to write your own equality comparer.
如果您想要一个想要相交的单个属性的列表,那么所有其他漂亮的 LINQ 解决方案都可以正常工作。但!如果你想在整个类上相交,结果有一个List<ThisClass>而不是List<string>你必须编写自己的相等比较器。
foo.Intersect(bar, new YourEqualityComparer());
same with Except.
与Except.
public class YourEqualityComparer: IEqualityComparer<ThisClass>
{
#region IEqualityComparer<ThisClass> Members
public bool Equals(ThisClass x, ThisClass y)
{
//no null check here, you might want to do that, or correct that to compare just one part of your object
return x.a == y.a && x.b == y.b;
}
public int GetHashCode(ThisClass obj)
{
unchecked
{
var hash = 17;
//same here, if you only want to get a hashcode on a, remove the line with b
hash = hash * 23 + obj.a.GetHashCode();
hash = hash * 23 + obj.b.GetHashCode();
return hash;
}
}
#endregion
}
回答by Pongsathon.keng
You should create IEqualityComparer. You can pass the IEqualityComparer to Intersect() method. This will help you get List(which intersect with bar) easier.
您应该创建 IEqualityComparer。您可以将 IEqualityComparer 传递给 Intersect() 方法。这将帮助您更轻松地获得 List(与 bar 相交)。
var intersectionList = foo.Intersect(bar, new ThisClassEqualityComparer()).ToList();
class ThisClassEqualityComparer : IEqualityComparer<ThisClass>
{
public bool Equals(ThisClass b1, ThisClass b2)
{
return b1.a == b2.a;
}
public int GetHashCode(Box bx)
{
// To ignore to compare hashcode, please consider this.
// I would like to force Equals() to be called
return 0;
}
}
回答by Avner Shahar-Kashtan
What exactly is the desired effect? Do you want to get a list of strings composed of all the a's in your classes, or a list of ThisClass, when two ThisClassinstances are identified via unique values of a?
想要的效果究竟是什么?当通过 的唯一值标识两个实例时a,您想要获取由类中的所有'组成的字符串列表,还是 的列表?ThisClassThisClassa
If it's the former, the two answers from @lazyberezovksy and @Tilak should work. If it's the latter, you'll have to override IEqualityComparer<ThisClass>or IEquatable<ThisClass>so that Intersectknows what makes two instances of ThisClassequivalent:
如果是前者,@lazyberezovksy 和 @Tilak 的两个答案应该有效。如果是后者,您将不得不重写IEqualityComparer<ThisClass>orIEquatable<ThisClass>以便Intersect知道是什么使两个实例ThisClass等效:
private class ThisClass : IEquatable<ThisClass>
{
private string a;
public bool Equals(ThisClass other)
{
return string.Equals(this.a, other.a);
}
}
then you can just call:
然后你可以打电话:
var intersection = foo.Intersect(bar);
回答by Zach Johnson
Not sure of the speed of this compared to intersect and compare but how about:
不确定与相交和比较相比的速度,但如何:
//Intersect
var inter = foo.Where(f => bar.Any(b => b.a == f.a));
//Except - values of foo not in bar
var except = foo.Where(f => !bar.Any(b => b.a == f.a));
回答by tyr
I know this is old but couldn't you also just override the Equals & GetHashCode on the class itself?
我知道这是旧的,但你不能也只覆盖类本身的 Equals & GetHashCode 吗?
class ThisClass
{
public string a {get; set;}
private string b {get; set;}
public override bool Equals(object obj)
{
// If you only want to compare on a
ThisClass that = (ThisClass)obj;
return string.Equals(a, that.a/* optional: not case sensitive? */);
}
public override int GetHashCode()
{
return a.GetHashCode();
}
}

