Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 比较两个列表并仅在Linq中获取不同的项_C#_Linq - Fatal编程技术网

C# 比较两个列表并仅在Linq中获取不同的项

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

我的对象有3个字段-学生、学期、科目和分数。我想有一个项目的清单,任何科目的分数都不一样

例如:

 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;
}