当数据需要分组时,我试图弄清楚如何计算与前一项的差异。
我有这样的数据
City Area Date Citizens
New York 1 2010.11.20 5
New York 1 2010.11.21 8
New York 1 2010.11.22 12
New York 1 2010.11.23 17
New York 1 2010.11.24 23
New York 1 2010.11.25 29
Chicago 1 2010.11.20 5
Chicago 1 2010.11.21 10
Chicago 1 2010.11.22 15
Chicago 1 2010.11.23 20
Chicago 1 2010.11.24 25
Chicago 1 2010.11.25 30
New York 2 2010.11.20 6
New York 2 2010.11.21 7
New York 2 2010.11.22 9
New York 2 2010.11.23 7
New York 2 2010.11.24 10
New York 2 2010.11.25 15
Chicago 2 2010.11.20 5
Chicago 2 2010.11.21 15
Chicago 2 2010.11.22 25
Chicago 2 2010.11.23 20
Chicago 2 2010.11.24 25
Chicago 2 2010.11.25 30
Run Code Online (Sandbox Code Playgroud)
我需要为每个城市的每个城市添加一列“增加”,这将通过从当前人数中减去以前的公民人数来计算。
The expected result is like this
City Area Date Citizens Increase
New York 1 2010.11.20 5 5
New York 1 2010.11.21 8 3
New York 1 2010.11.22 12 4
New York 1 2010.11.23 17 5
New York 1 2010.11.24 23 6
New York 1 2010.11.25 29 7
Chicago 1 2010.11.20 5 5
Chicago 1 2010.11.21 10 5
Chicago 1 2010.11.22 15 5
Chicago 1 2010.11.23 20 5
Chicago 1 2010.11.24 25 5
Chicago 1 2010.11.25 30 5
New York 2 2010.11.20 6 6
New York 2 2010.11.21 7 1
New York 2 2010.11.22 9 2
New York 2 2010.11.23 7 -2
New York 2 2010.11.24 10 3
New York 2 2010.11.25 15 5
Chicago 2 2010.11.20 5 5
Chicago 2 2010.11.21 15 10
Chicago 2 2010.11.22 25 10
Chicago 2 2010.11.23 20 -5
Chicago 2 2010.11.24 25 5
Chicago 2 2010.11.25 30 5
Run Code Online (Sandbox Code Playgroud)
我想知道这是否可以通过单个 linq 查询来完成,避免“foreach (c in city) foreach (a in area) ....”
问题是如何计算行“7”,其中与前一条记录的简单差异为 -24,何时应为 5。
这是一个示例代码:
using System;
using System.Collections.Generic;
namespace ConsoleApplication1
{
public class MyObject
{
public int ID { get; set; }
public string City { get;set; }
public DateTime Date { get; set; }
public int Value { get; set; }
public int DiffToPrev { get; set; }
}
class Program
{
static void Main()
{
var list = new List<MyObject>
{
new MyObject {ID= 1, City = "New York",Date = DateTime.Now, Value = 5},
new MyObject {ID= 1, City = "New York",Date = DateTime.Now.AddDays(1),Value = 8},
new MyObject {ID= 1, City = "New York",Date = DateTime.Now.AddDays(2),Value = 12},
new MyObject {ID= 1, City = "New York",Date = DateTime.Now.AddDays(3),Value = 17},
new MyObject {ID= 1, City = "New York",Date = DateTime.Now.AddDays(4),Value = 23},
new MyObject {ID= 1, City = "New York",Date = DateTime.Now.AddDays(5),Value = 29},
new MyObject {ID= 1, City = "Chicago",Date = DateTime.Now, Value = 5},
new MyObject {ID= 1, City = "Chicago",Date = DateTime.Now.AddDays(1),Value = 10},
new MyObject {ID= 1, City = "Chicago",Date = DateTime.Now.AddDays(2),Value = 15},
new MyObject {ID= 1, City = "Chicago",Date = DateTime.Now.AddDays(3),Value = 20},
new MyObject {ID= 1, City = "Chicago",Date = DateTime.Now.AddDays(4),Value = 25},
new MyObject {ID= 1, City = "Chicago",Date = DateTime.Now.AddDays(5),Value = 30},
new MyObject {ID= 2, City = "New York",Date = DateTime.Now, Value = 6},
new MyObject {ID= 2, City = "New York",Date = DateTime.Now.AddDays(1),Value = 7},
new MyObject {ID= 2, City = "New York",Date = DateTime.Now.AddDays(2),Value = 9},
new MyObject {ID= 2, City = "New York",Date = DateTime.Now.AddDays(3),Value = 7},
new MyObject {ID= 2, City = "New York",Date = DateTime.Now.AddDays(4),Value = 10},
new MyObject {ID= 2, City = "New York",Date = DateTime.Now.AddDays(5),Value = 15},
new MyObject {ID= 2, City = "Chicago",Date = DateTime.Now, Value = 5},
new MyObject {ID= 2, City = "Chicago",Date = DateTime.Now.AddDays(1),Value = 15},
new MyObject {ID= 2, City = "Chicago",Date = DateTime.Now.AddDays(2),Value = 25},
new MyObject {ID= 2, City = "Chicago",Date = DateTime.Now.AddDays(3),Value = 20},
new MyObject {ID= 2, City = "Chicago",Date = DateTime.Now.AddDays(4),Value = 25},
new MyObject {ID= 2, City = "Chicago",Date = DateTime.Now.AddDays(5),Value = 30},
};
}
}
}
Run Code Online (Sandbox Code Playgroud)
你可以这样做:
var newList = list.GroupBy(x => new { x.City, x.ID })
.Select
(
x =>
{
var subList = x.OrderBy(y => y.Date).ToList();
return subList.Select((y, idx) => new MyObject
{
ID = y.ID,
City = y.City,
Date = y.Date,
Value = y.Value,
DiffToPrev = (idx == 0) ? y.Value : y.Value - subList.ElementAt(idx-1).Value
});
}
)
.SelectMany(x => x)
.ToList();
Run Code Online (Sandbox Code Playgroud)
无论如何,我认为在这种情况下 foreach 语句更清晰(而不是更长),例如:
List<MyObject> newList = new List<MyObject>();
foreach (var grp in list.GroupBy(x => new { x.City, x.ID }))
{
MyObject prev = null;
foreach (var obj in grp.OrderBy(y => y.Date))
{
newList.Add(new MyObject
{
ID = obj.ID,
City = obj.City,
Date = obj.Date,
Value = obj.Value,
DiffToPrev = (prev == null) ? obj.Value : obj.Value - prev.Value
});
prev = obj;
}
}
Run Code Online (Sandbox Code Playgroud)
PS
显然(取决于您的需要)在 foreach 代码中,您可以DiffToPrev直接在现有对象 ( obj)上设置 ,而不是创建一个新对象,从而可以选择创建newList.
结果:
ID: 1,City: New York,Date: 21/11/2010 12:52:40,Value: 5,Diff: 5
ID: 1,City: New York,Date: 22/11/2010 12:52:40,Value: 8,Diff: 3
ID: 1,City: New York,Date: 23/11/2010 12:52:40,Value: 12,Diff: 4
ID: 1,City: New York,Date: 24/11/2010 12:52:40,Value: 17,Diff: 5
ID: 1,City: New York,Date: 25/11/2010 12:52:40,Value: 23,Diff: 6
ID: 1,City: New York,Date: 26/11/2010 12:52:40,Value: 29,Diff: 6
ID: 1,City: Chicago,Date: 21/11/2010 12:52:40,Value: 5,Diff: 5
ID: 1,City: Chicago,Date: 22/11/2010 12:52:40,Value: 10,Diff: 5
ID: 1,City: Chicago,Date: 23/11/2010 12:52:40,Value: 15,Diff: 5
ID: 1,City: Chicago,Date: 24/11/2010 12:52:40,Value: 20,Diff: 5
ID: 1,City: Chicago,Date: 25/11/2010 12:52:40,Value: 25,Diff: 5
ID: 1,City: Chicago,Date: 26/11/2010 12:52:40,Value: 30,Diff: 5
ID: 2,City: New York,Date: 21/11/2010 12:52:40,Value: 6,Diff: 6
ID: 2,City: New York,Date: 22/11/2010 12:52:40,Value: 7,Diff: 1
ID: 2,City: New York,Date: 23/11/2010 12:52:40,Value: 9,Diff: 2
ID: 2,City: New York,Date: 24/11/2010 12:52:40,Value: 7,Diff: -2
ID: 2,City: New York,Date: 25/11/2010 12:52:40,Value: 10,Diff: 3
ID: 2,City: New York,Date: 26/11/2010 12:52:40,Value: 15,Diff: 5
ID: 2,City: Chicago,Date: 21/11/2010 12:52:40,Value: 5,Diff: 5
ID: 2,City: Chicago,Date: 22/11/2010 12:52:40,Value: 15,Diff: 10
ID: 2,City: Chicago,Date: 23/11/2010 12:52:40,Value: 25,Diff: 10
ID: 2,City: Chicago,Date: 24/11/2010 12:52:40,Value: 20,Diff: -5
ID: 2,City: Chicago,Date: 25/11/2010 12:52:40,Value: 25,Diff: 5
ID: 2,City: Chicago,Date: 26/11/2010 12:52:40,Value: 30,Diff: 5
ID: 1,City: New York,Date: 21/11/2010 12:52:40,Value: 5,Diff: 5
ID: 1,City: New York,Date: 22/11/2010 12:52:40,Value: 8,Diff: 3
ID: 1,City: New York,Date: 23/11/2010 12:52:40,Value: 12,Diff: 4
ID: 1,City: New York,Date: 24/11/2010 12:52:40,Value: 17,Diff: 5
ID: 1,City: New York,Date: 25/11/2010 12:52:40,Value: 23,Diff: 6
ID: 1,City: New York,Date: 26/11/2010 12:52:40,Value: 29,Diff: 6
ID: 1,City: Chicago,Date: 21/11/2010 12:52:40,Value: 5,Diff: 5
ID: 1,City: Chicago,Date: 22/11/2010 12:52:40,Value: 10,Diff: 5
ID: 1,City: Chicago,Date: 23/11/2010 12:52:40,Value: 15,Diff: 5
ID: 1,City: Chicago,Date: 24/11/2010 12:52:40,Value: 20,Diff: 5
ID: 1,City: Chicago,Date: 25/11/2010 12:52:40,Value: 25,Diff: 5
ID: 1,City: Chicago,Date: 26/11/2010 12:52:40,Value: 30,Diff: 5
ID: 2,City: New York,Date: 21/11/2010 12:52:40,Value: 6,Diff: 6
ID: 2,City: New York,Date: 22/11/2010 12:52:40,Value: 7,Diff: 1
ID: 2,City: New York,Date: 23/11/2010 12:52:40,Value: 9,Diff: 2
ID: 2,City: New York,Date: 24/11/2010 12:52:40,Value: 7,Diff: -2
ID: 2,City: New York,Date: 25/11/2010 12:52:40,Value: 10,Diff: 3
ID: 2,City: New York,Date: 26/11/2010 12:52:40,Value: 15,Diff: 5
ID: 2,City: Chicago,Date: 21/11/2010 12:52:40,Value: 5,Diff: 5
ID: 2,City: Chicago,Date: 22/11/2010 12:52:40,Value: 15,Diff: 10
ID: 2,City: Chicago,Date: 23/11/2010 12:52:40,Value: 25,Diff: 10
ID: 2,City: Chicago,Date: 24/11/2010 12:52:40,Value: 20,Diff: -5
ID: 2,City: Chicago,Date: 25/11/2010 12:52:40,Value: 25,Diff: 5
ID: 2,City: Chicago,Date: 26/11/2010 12:52:40,Value: 30,Diff: 5
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3572 次 |
| 最近记录: |