我有两个IList类型的对象:
public class SampleSentence
{
public int SampleSentenceId { get; set; }
public string Text { get; set; }
}
IList<SampleSentence> Old =
[new SampleSentence() { SampleSentenceId = 1; Text = 'cat' }]
IList<SampleSentence> New =
[new SampleSentence() { Text = 'cat' }],
new SampleSentence() { Text = 'dog' }]
我需要得到的是:
IList<SampleSentence> whatINeed =
[new SampleSentence() { Text = 'dog' }]
Old
是SampleSentences的列表,其中填充了SampleSentenceId和Text字段。 New
是SampleSentences的列表,只填充了文本字段。它将与对象Old
使用LINQ如何比较Old
和New
个对象(将它们与Text的内容相关联)并创建另一个IList,它在名为New
的列表中有其他列?
答案 0 :(得分:3)
创建自定义IEqualityComparer:
public class SampleSentenceComparer : IEqualityComparer<SampleSentence> {
public bool Equals(SampleSentence x, SampleSentence y) {
if (x == y) return true;
if (x == null || y == null) return false;
return x.Text.Equals(y.Text);
}
public int GetHashCode(SampleSentence obj) {
return obj.Text.GetHashCode();
}
}
用法:
List<SampleSentence> newItems = New.Except(Old, new SampleSentenceComparer()).ToList();
答案 1 :(得分:3)
您可以使用LINQ antijoin方法/运算符实现的简单GroupJoin
:
IList<SampleSentence> whatINeed = New.GroupJoin(Old,
newElement => newElement.Text, oldElement => oldElement.Text,
(newElement, oldElements) => new { newElement, oldElements })
.Where(match => !match.oldElements.Any())
.Select(match => match.newElement)
.ToList();
与查询语法相同(由于透明标识符而使用连接时更可取 - 请注意缺少match
匿名类型):
IList<SampleSentence> whatINeed =
(from newElement in New
join oldElement in Old on newElement.Text equals oldElement.Text into oldElements
where !oldElements.Any()
select newElement)
.ToList();