我的对象有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#)
执行此操作答案 0 :(得分:1)
实际上,有很多方法可以做到这一点。一个提到使用自定义比较器。一个人使用了字典,但这并不是必需的。
// 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 :(得分:0)
这可能是你想要的(但不幸的是没有测试......):
var result = secondList.Union(firstList)
.GroupBy(m => Tuple.Create(m.Student, m.Subject))
.ToDictionary(m => m.Key, n => n.OrderBy(m=>m.Term).Select(s => s.Marks).Aggregate((t1, t2) => t2 - t1))
.Where(m=>m.Value != 0);
答案 2 :(得分:0)
var comparer = new SomeClassComparer(); /*must implement IEaualityComparer<SomeClass>*/
var list1 = new List<SomeClass>() { /*...*/ };
var list2 = new List<SomeClass>() { /*...*/};
var result = list1.Except(list2, comparer).Union(list2.Except(list1, comparer));