如何使用LINQ实现关联上一条记录并计算当日与前日进食量差值
如何使用LINQ实现关联上一条记录并计算当日与前日进食量差值
当然可以用LINQ搞定这个需求!我来帮你一步步拆解怎么弄~
先明确需求逻辑
从你的结果示例来看,你需要:
- 把记录按日期从新到旧排序
- 每条记录的
CompareToFoodFromYesterday= 当前记录的EatenFoodInKg- 排序后下一条记录的EatenFoodInKg - 最早的那条记录(最后一条)没有下一条,所以可以留空或保持默认值
为什么之前的思路没成功?
你说合并两个相同列表不行,其实不是不能合并,而是要错位合并——把排序后的列表,和「排序后跳过第一个的列表」合并,这样每一对就正好是「当前记录」和「它的上一条(时间更早的)记录」啦。
具体LINQ实现代码
首先我们先把原列表按日期降序排序,然后用两种方法实现:
方法一:用Zip错位合并列表
Zip方法可以把两个序列按位置一一配对,我们用它把排序后的列表和「排序后跳过第一个的列表」合并,正好拿到当前记录和下一条记录:
// 先按日期从新到旧排序原列表 var sortedPeople = list1.OrderByDescending(p => p.Date).ToList(); // 用Zip合并当前列表和跳过第一个的列表,计算差值 var result = sortedPeople .Zip(sortedPeople.Skip(1), (current, next) => { current.CompareToFoodFromYesterday = current.EatenFoodInKg - next.EatenFoodInKg; return current; }) // 把最后一条(最早的记录)加回来,因为Zip会漏掉它 .Concat(sortedPeople.TakeLast(1)) .ToList();
方法二:用带索引的Select访问下一条记录
如果觉得Zip不好理解,也可以用带索引的Select,直接通过索引获取下一条记录:
var sortedPeople = list1.OrderByDescending(p => p.Date).ToList(); var result = sortedPeople .Select((person, index) => { // 不是最后一条的话,找到下一条记录计算差值 if (index < sortedPeople.Count - 1) { var previousRecord = sortedPeople[index + 1]; person.CompareToFoodFromYesterday = person.EatenFoodInKg - previousRecord.EatenFoodInKg; } // 最后一条记录没有上一条,保留默认值即可 return person; }) .ToList();
如果你需要严格匹配「前一天的日期」(不是排序后的下一条)
如果你的需求是找日期正好是前一天的记录(而不管中间有没有缺失日期),可以改成通过日期匹配:
var result = list1 .Select(p => { // 找日期正好是当前日期前一天的记录 var previousDayPerson = list1.FirstOrDefault(x => x.Date == p.Date.AddDays(-1)); if (previousDayPerson != null) { p.CompareToFoodFromYesterday = p.EatenFoodInKg - previousDayPerson.EatenFoodInKg; } return p; }) .OrderByDescending(p => p.Date) .ToList();
验证结果
用你的示例数据测试,第一种方法会得到和你给出的Result完全一致的结果:
- 2000-01-11的
CompareToFoodFromYesterday= 10 - 1 = 9 - 2000-01-10的
CompareToFoodFromYesterday= 1 - 6 = -5 - ...以此类推,最后一条2000-01-01没有上一条,保留默认值
内容来源于stack exchange
相关产品推荐
相关产品推荐

