如何根据属性list A
将list B
对象类型人与Name
人进行比较,并获取另一个list C
包含两个列表中常见的人{} {1}}但不在list D
中的{1}}
答案 0 :(得分:1)
var a = new List<int>();
var b = new List<int>();
var c = new List<int>();
var d = new List<int>();
c = a.Where(aItem => b.Any(bItem => aItem == bItem)).ToList();
d = a.Except(c).ToList();
您可以使用任何逻辑将项目与项目进行比较。
这是扩展方法。
public static class LinqEx
{
public static bool DefaultCompare<T>(T one, T two)
{
return one.Equals(two);
}
public static IEnumerable<T> Common<T>(this IEnumerable<T> first, IEnumerable<T> second)
{
return first.Common(second, DefaultCompare);
}
public static IEnumerable<T> Common<T>(this IEnumerable<T> first, IEnumerable<T> second, Func<T, T, bool> compare)
{
return first.Where(i1 => second.Any(i2 => compare(i1, i2)));
}
public static IEnumerable<T> Common<T>(this IEnumerable<T> first, IEnumerable<T> second, out IEnumerable<T> difference)
{
return first.Common(second, out difference, DefaultCompare);
}
public static IEnumerable<T> Common<T>(this IEnumerable<T> first, IEnumerable<T> second, out IEnumerable<T> difference, Func<T, T, bool> compare)
{
var common = first.Common(second, compare);
difference = first.Except(common);
return common;
}
public static IEnumerable<T> Common<T>(this IEnumerable<T> first, IEnumerable<T> second, out List<T> difference)
{
IEnumerable<T> d;
var common = first.Common(second, out d);
difference = d.ToList();
return common;
}
public static IEnumerable<T> Common<T>(this IEnumerable<T> first, IEnumerable<T> second, out List<T> difference, Func<T, T, bool> compare)
{
IEnumerable<T> d;
var common = first.Common(second, out d, compare);
difference = d.ToList();
return common;
}
}
用法:
List<myObjectType> d;
c = a.Common(b, out d, (i1, i2) => i1.Name == i2.Name).ToList();
答案 1 :(得分:1)
我的答案与其他人的答案相似,但前半部分使用Intersect()
方法,这是最简单,最正确的正确方式,我觉得,获取两个集合中都存在的项目:
var a = new[] {new Person("Alice"), new Person("Bob")};
var b = new[] {new Person("Bob"), new Person("Charlie")};
var inBoth = a.Intersect(b, new PersonNameEqualityComparer());
var notInB = a.Except(b, , new PersonNameEqualityComparer());
inBoth
将包含Bob,而notInB
将包含Alice。
这里唯一的问题是Intersect
需要一个相等比较器,它可以获得两个Person对象,并根据它们的Name确定它们是否相等。我希望我们可以在这里指定一个lambda表达式,但在此之前,实现很简单:
class PersonNameEqualityComparer : IEqualityComparer<Person>
{
public bool Equals(Person x, Person y)
{
return x.Name == y.Name;
}
public int GetHashCode(Person obj)
{
return obj.Name.GetHashCode();
}
}
答案 2 :(得分:0)
简短的回答如下:
var c = listA.Join(listB, a => a.Name, b => b.Name, (a, b) => a).ToList();
var d = listA.Except(c).ToList();
这将基于每个对象的Name
属性连接两个列表,并将从第一个列表返回公共对象。 Except()
方法将返回listA
bot中不在c
中的对象;使用Object.ReferenceEquals()
进行比较,如果您将(a, b) => a
更改为(a, b) => b
,则该方法将失败。
要避免这种情况,您必须实现IEqualityComparer<Person>
并将其传递给方法Except()
,如下所示:
var comparer = new PersonComparer(); // the class that implements IEqualityComparer<Person>
var d = listA.Except(c, comparer).ToList();