Ответ 1
Может
// returns list of intersecting property 'a' values
foo.Select(f => f.a).Intersect(bar.Select(b => b.a));
Свойство BTW a
должно быть общедоступным.
Я осмотрелся и не могу найти ничего, чтобы помочь здесь. У меня класс:
class ThisClass
{
private string a {get; set;}
private string b {get; set;}
}
Я хотел бы использовать методы Intersect и Except Linq, т.е.
private List<ThisClass> foo = new List<ThisClass>();
private List<ThisClass> bar = new List<ThisClass>();
Затем я заполняю два списка отдельно. Я хотел бы сделать, например (и я знаю, что это неправильно, просто псевдокод), следующее:
foo[a].Intersect(bar[a]);
Как мне это сделать?
Спасибо за любую помощь:)
Может
// returns list of intersecting property 'a' values
foo.Select(f => f.a).Intersect(bar.Select(b => b.a));
Свойство BTW a
должно быть общедоступным.
Если вам нужен список одного свойства, которое вы хотели бы пересечь, тогда все остальные красивые решения LINQ работают нормально.
НО! Если вы хотите пересечься по всему классу, и в результате получим List<ThisClass>
вместо List<string>
, вам придется написать собственный сопоставитель сравнений.
foo.Intersect(bar, new YourEqualityComparer());
то же самое с 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
}
Не уверен в скорости этого по сравнению с пересечением и сравнением, но как насчет:
//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));
foo.Select(x=>x.a).Intersect(bar.Select(x=>x.a))
Что такое желаемый эффект? Вы хотите получить список строк, состоящих из всех a
в ваших классах, или список ThisClass
, когда два экземпляра ThisClass
идентифицируются с помощью уникальных значений a
?
Если это первый, два ответа от @lazyberezovksy и @Tilak должны работать. Если это последнее, вам придется переопределить IEqualityComparer<ThisClass>
или IEquatable<ThisClass>
, чтобы Intersect
знал, что делает два экземпляра эквивалента ThisClass
:
private class ThisClass : IEquatable<ThisClass>
{
private string a;
public bool Equals(ThisClass other)
{
return string.Equals(this.a, other.a);
}
}
то вы можете просто позвонить:
var intersection = foo.Intersect(bar);
Я знаю, что это старо, но не могли бы вы просто переопределить 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();
}
}
Вы должны создать IEqualityComparer. Вы можете передать метод IEqualityComparer в метод Intersect(). Это поможет вам легче получить список (который пересекает панель).
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;
}
}