C# 比较两个列表并仅在Linq中获取不同的项
我的对象有3个字段-学生、学期、科目和分数。我想有一个项目的清单,任何科目的分数都不一样 例如:C# 比较两个列表并仅在Linq中获取不同的项,c#,linq,C#,Linq,我的对象有3个字段-学生、学期、科目和分数。我想有一个项目的清单,任何科目的分数都不一样 例如: First list is Alice, Term1, English,90 Alice, Term1, Maths, 60 Alice, Term1, Physics, 30 Second list is Alice, Term2, English, 95
First list is
Alice, Term1, English,90
Alice, Term1, Maths, 60
Alice, Term1, Physics, 30
Second list is
Alice, Term2, English, 95
Alice, Term2,Maths, 60
Alice, Term2, Physics, 20
在最后的列表中,我只想得到差值
艾丽斯,英语+5
艾丽斯,物理-10
我如何使用Linq(c#)实现这一点这可能是您想要的(但不幸的是没有测试过…):
var comparer=newsomeclasscomparer()/*必须实施IEAULITYCOMPARER*/
var list1=new List(){/*…*/};
var list2=new List(){/*…*/};
var result=list1.Except(list2,comparer).Union(list2.Except(list1,comparer));
实际上,有很多方法可以做到这一点。其中一个提到使用自定义比较器。有人用过字典,尽管那不是必要的
// 1) use group by and only select groups with one item in them
var qqq = from r in one.Union(two)
group r by new { r.Term, r.Mark } into g
where g.Count() == 1
select g.First();
// 2) work from a complete list and then remove stuff
var all = one.Union(two).ToList();
// select only the records that have a count of one
var uniq = from a in all
where all.Count(y => y.Term == a.Term && y.Mark == a.Mark) == 1
select a;
// -or- find all the duplicates and the remove them
var dupes = all.Where(x => all.Count(y => y.Term == x.Term && y.Mark == x.Mark) > 1).ToList();
var uniq = all.Except(dupes).ToList();
有太多的方法可以做到这一点
编辑
现在我有时间思考了,似乎有一种简单的方法可以一步完成这一切。不确定全部要求,但这里是:
var calcd = from t1 in one
let t2 = two.FirstOrDefault(x => DataMatch(t1, x))
where t2 != null
select new {
Name = t1.Name,
Class = t1.Class,
Change = t2.Mark - t1.Mark
};
public static bool DataMatch(Data x, Data y)
{
return x.Name == y.Name && x.Class == y.Class &&
x.Term != y.Term && x.Mark != y.Mark;
}
// 1) use group by and only select groups with one item in them
var qqq = from r in one.Union(two)
group r by new { r.Term, r.Mark } into g
where g.Count() == 1
select g.First();
// 2) work from a complete list and then remove stuff
var all = one.Union(two).ToList();
// select only the records that have a count of one
var uniq = from a in all
where all.Count(y => y.Term == a.Term && y.Mark == a.Mark) == 1
select a;
// -or- find all the duplicates and the remove them
var dupes = all.Where(x => all.Count(y => y.Term == x.Term && y.Mark == x.Mark) > 1).ToList();
var uniq = all.Except(dupes).ToList();
var calcd = from t1 in one
let t2 = two.FirstOrDefault(x => DataMatch(t1, x))
where t2 != null
select new {
Name = t1.Name,
Class = t1.Class,
Change = t2.Mark - t1.Mark
};
public static bool DataMatch(Data x, Data y)
{
return x.Name == y.Name && x.Class == y.Class &&
x.Term != y.Term && x.Mark != y.Mark;
}