比较列表并获得唯一的元素
本文关键字:唯一 元素 列表 比较 | 更新日期: 2023-09-27 17:50:30
我有一个名为Parent的对象和一个名为Child的对象列表。Parent对象也有一个Child对象的列表。
public class Parent
{
public Parent()
{
Children = new List<Child>();
}
public string Name { get; set; }
public IList<Child> Children { get; set; }
}
public class Child
{
public string Name { get; set; }
....
}
现在我想从列表中获取那些不存在于Parent's list of Children中的Children.
我怎么能实现这与linq/lambda表达式?
我试过的代码没有成功:
Parent parent = GetParent();
List<Child> children = GetChildren();
var notExistingChildren = children.Where(child => !parent.Children.Any(ch => ch.Name == child.Name)).ToList();
子元素有一个父元素中不存在的元素。
您的方法不是很有效,因为您为children
集合中的每个子枚举父子。此外,如果名称有不同的大小写,您可能会遇到问题-例如,"Bob"
和"bob"
在c#中是不同的字符串。但是,如果名称相等,您的方法应该有效:
var notExistingChildren =
children.Where(c => !parent.Children.Any(pc => pc.Name == c.Name))
.ToList();
更有效和易于阅读的方式是为Child
类实现Equals
和GetHashCode
方法(或为Child
类创建自定义IEqualityComparer
)。在这种情况下,您将能够使用Enumerable.Except
执行设置操作:
var notExistingChildren = children.Except(parent.Children).ToList();
如果子名称可以作为它的标识,那么你可以用以下方式覆盖Equals
和GetHashCode
:
public override bool Equals(object obj)
{
Child other = obj as Child;
if (other == null)
return false;
return other.Name == Name;
}
public override int GetHashCode()
{
return Name.GetHashCode();
}
顺便说一句,我用下面的样本数据尝试了你的代码,它工作得很好- Joe返回为不存在的孩子。
List<Child> children = new List<Child>
{
new Child { Name = "Bob" },
new Child { Name = "Joe" }
};
Parent parent = new Parent
{
Children = new List<Child> { new Child { Name = "Bob" } }
};
如果在results中没有看到child,则parents children collection中存在同名的child。没有别的办法。
这个表达式对我来说很好。使用ch.Name.ToLower() == child.Name.ToLower()进行比较,因为您的列表可能有不同的字符大小写