[英]Group By timespan in LINQ
假設我們有一個類似的類:
class Forecast
{
int LocationId;
int DepartmentId;
DateTime StartDate;
DateTime EndDate;
int CountOfEmployees;
}
我有一個預測List<Forecasts> forecasts
: List<Forecasts> forecasts
該列表按15分鍾間隔分組,例如:
forecast[0] = new Forecast { LocationId = 1, DepartmentId = 1, StartTime = 2018-10-01 06:00:00.000, EndTime = 2018-10-01 06:15:00.000, CountOfEmployees = 2 }
forecast[1] = new Forecast { LocationId = 1, DepartmentId = 1, StartTime = 2018-10-01 06:15:00.000, EndTime = 2018-10-01 06:30:00.000, CountOfEmployees = 1 }
forecast[2] = new Forecast { LocationId = 1, DepartmentId = 1, StartTime = 2018-10-01 06:30:00.000, EndTime = 2018-10-01 06:45:00.000, CountOfEmployees = 3 }
forecast[3] = new Forecast { LocationId = 1, DepartmentId = 1, StartTime = 2018-10-01 06:45:00.000, EndTime = 2018-10-01 07:00:00.000, CountOfEmployees = 1 }
forecast[4] = new Forecast { LocationId = 1, DepartmentId = 1, StartTime = 2018-10-01 07:00:00.000, EndTime = 2018-10-01 07:15:00.000, CountOfEmployees = 2 }
forecast[5] = new Forecast { LocationId = 1, DepartmentId = 1, StartTime = 2018-10-01 07:15:00.000, EndTime = 2018-10-01 07:30:00.000, CountOfEmployees = 2 }
forecast[6] = new Forecast { LocationId = 1, DepartmentId = 1, StartTime = 2018-10-01 07:30:00.000, EndTime = 2018-10-01 07:45:00.000, CountOfEmployees = 5 }
forecast[7] = new Forecast { LocationId = 1, DepartmentId = 1, StartTime = 2018-10-01 07:45:00.000, EndTime = 2018-10-01 08:00:00.000, CountOfEmployees = 3 }
forecast[8] = new Forecast { LocationId = 2, DepartmentId = 2, StartTime = 2018-10-01 06:00:00.000, EndTime = 2018-10-01 06:15:00.000, CountOfEmployees = 2 }
forecast[9] = new Forecast { LocationId = 2, DepartmentId = 2, StartTime = 2018-10-01 06:15:00.000, EndTime = 2018-10-01 06:30:00.000, CountOfEmployees = 1 }
forecast[10] = new Forecast { LocationId = 2, DepartmentId = 2, StartTime = 2018-10-01 06:30:00.000, EndTime = 2018-10-01 06:45:00.000, CountOfEmployees = 3 }
forecast[11] = new Forecast { LocationId = 2, DepartmentId = 2, StartTime = 2018-10-01 06:45:00.000, EndTime = 2018-10-01 07:00:00.000, CountOfEmployees = 1 }
forecast[12] = new Forecast { LocationId = 2, DepartmentId = 2, StartTime = 2018-10-01 07:00:00.000, EndTime = 2018-10-01 07:15:00.000, CountOfEmployees = 2 }
forecast[13] = new Forecast { LocationId = 2, DepartmentId = 2, StartTime = 2018-10-01 07:15:00.000, EndTime = 2018-10-01 07:30:00.000, CountOfEmployees = 2 }
forecast[14] = new Forecast { LocationId = 2, DepartmentId = 2, StartTime = 2018-10-01 07:30:00.000, EndTime = 2018-10-01 07:45:00.000, CountOfEmployees = 5 }
forecast[15] = new Forecast { LocationId = 2, DepartmentId = 2, StartTime = 2018-10-01 07:45:00.000, EndTime = 2018-10-01 08:00:00.000, CountOfEmployees = 3 }
我希望將結果在60分鍾的時間間隔,位置和部門以及countOfEmployees的總和中分組。 因此,預期結果應該是這樣的:
result[0] = new Forecast { LocationId = 1, DepartmentId = 1, StartTime = 2018-10-01 06:00:00.000, EndTime = 2018-10-01 07:00:00.000, CountOfEmployees = 7 }
result[1] = new Forecast { LocationId = 1, DepartmentId = 1, StartTime = 2018-10-01 07:00:00.000, EndTime = 2018-10-01 08:00:00.000, CountOfEmployees = 12 }
result[2] = new Forecast { LocationId = 2, DepartmentId = 2, StartTime = 2018-10-01 07:00:00.000, EndTime = 2018-10-01 08:00:00.000, CountOfEmployees = 12 }
result[3] = new Forecast { LocationId = 2, DepartmentId = 2, StartTime = 2018-10-01 07:00:00.000, EndTime = 2018-10-01 08:00:00.000, CountOfEmployees = 12 }
有人能指出我正確的方向嗎?
您可以嘗試將linq select
與group by
一起使用
在linq GroupBy
為您的EndTime
, StartTime
, LocationId
邏輯建立時間分組
每小時的StartTime
和EndTime
。
var result = forecast
.GroupBy(_ => new {
_.LocationId,
StartTime = new DateTime(_.StartTime.Year,
_.StartTime.Month,
_.StartTime.Day,
_.StartTime.Hour,0,0,0),
EndTime = new DateTime(_.StartTime.Year,
_.StartTime.Month,
_.StartTime.Day,
_.StartTime.Hour + 1, 0, 0, 0)
})
.Select(x => new {
x.Key.LocationId,
x.Key.StartTime,
x.Key.EndTime,
CountOfEmployees = x.Sum(y=>y.CountOfEmployees)});
結果
LocationId : 1 StartTime : 10/1/2018 6:00:00 AM EndTime : 10/1/2018 7:00:00 AM CountOfEmployees : 7
LocationId : 1 StartTime : 10/1/2018 7:00:00 AM EndTime : 10/1/2018 8:00:00 AM CountOfEmployees : 12
LocationId : 2 StartTime : 10/1/2018 6:00:00 AM EndTime : 10/1/2018 7:00:00 AM CountOfEmployees : 7
LocationId : 2 StartTime : 10/1/2018 7:00:00 AM EndTime : 10/1/2018 8:00:00 AM CountOfEmployees : 12
您可以執行類似的操作,假設您的間隔始終從00分鍾到60分鍾開始,而不是從6:15到7:15。
var result = forecast.GroupBy(x=>new {x.StartTime.Hour, x.LocationId, x.DepartmentId})
.Select(x=> new Forecast
{
LocationId = x.Key.LocationId,
DepartmentId = x.Key.DepartmentId,
StartTime = x.ToList().OrderBy(e=>e.StartTime).First().StartTime,
EndTime = x.ToList().OrderBy(e=>e.EndTime).Last().EndTime,
CountOfEmployees = x.ToList().Sum(c=>c.CountOfEmployees)
});
這應該工作。 正如@SeM所述,您需要展示您的研究。 您的問題未顯示任何工作。
var results = from foreCastSelector in foreCasts
group foreCastSelector by new
{
LocationId = foreCastSelector.LocationId,
DepartmentId = foreCastSelector.DepartmentId,
StartDate = foreCastSelector.StartDate.AddMinutes(-1 * foreCastSelector.StartDate.Minute),
EndDate = foreCastSelector.StartDate.AddMinutes(-1 * foreCastSelector.StartDate.Minute).AddHours(1)
} into gcs
select new Forecast
{
LocationId = gcs.Key.LocationId,
DepartmentId = gcs.Key.DepartmentId,
StartDate = gcs.Key.StartDate,
EndDate = gcs.Key.EndDate,
CountOfEmployees = gcs.Sum(r => r.CountOfEmployees)
};
foreach (var result in results)
{
Console.WriteLine(result.LocationId + " | " + result.DepartmentId + " | "
+ result.StartDate.ToString() + " | "
+ result.EndDate.ToString() + " | "
+ result.CountOfEmployees);
}
您可以從時間中刪除分鍾,然后按新的StartTime
分組:
var result = forecast
.GroupBy(g => new { StartTime = g.StartTime.Date.AddHours(g.StartTime.Hour), g.LocationId, g.DepartmentId })
.Select(s =>
new Forecast()
{
LocationId = s.Key.LocationId,
DepartmentId = s.Key.DepartmentId,
StartTime = s.Key.StartTime,
EndTime = s.Max(m => m.EndTime),
CountOfEmployees = s.Sum(c => c.CountOfEmployees),
}
)
.OrderBy(o => o.LocationId)
.ThenBy(o => o.DepartmentId)
.ThenBy(o => o.StartTime)
.ToList();
或使用查詢語法:
var q = from f in forecast
group f by new
{
StartTime = f.StartTime.Date.AddHours(f.StartTime.Hour),
f.LocationId,
f.DepartmentId
} into g
orderby g.Key.LocationId, g.Key.DepartmentId, g.Key.StartTime
select new Forecast
{
LocationId = g.Key.LocationId,
DepartmentId = g.Key.DepartmentId,
StartTime = g.Key.StartTime,
EndTime = g.Max(m => m.EndTime),
CountOfEmployees = g.Sum(s => s.CountOfEmployees)
};
輸出:
LocationId: 1, DepartmentId: 1, StartTime: 10/1/2018 6:00:00, EndTime: 10/1/2018 7:00:00, CountOfEmployees: 7
LocationId: 1, DepartmentId: 1, StartTime: 10/1/2018 7:00:00, EndTime: 10/1/2018 8:00:00, CountOfEmployees: 12
LocationId: 2, DepartmentId: 2, StartTime: 10/1/2018 6:00:00, EndTime: 10/1/2018 7:00:00, CountOfEmployees: 7
LocationId: 2, DepartmentId: 2, StartTime: 10/1/2018 7:00:00, EndTime: 10/1/2018 8:00:00, CountOfEmployees: 12
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.