[英]C# LINQ Group by with the the same amount of items in each group
我無法弄清楚如何以這樣的正確方式對項目進行分組。 例如,我們有一個日期和團隊列表,如下所示:
日期 | 團隊 | 價值 |
---|---|---|
2021 年 1 月 1 日 | 團隊1 | 10 |
2021 年 1 月 1 日 | 團隊2 | 10 |
2021 年 1 月 1 日 | Team3 | 10 |
2021 年 1 月 2 日 | 團隊1 | 20 |
2021 年 1 月 2 日 | 團隊2 | 20 |
2021 年 1 月 3 日 | Team3 | 30 |
我希望它是這樣的:
日期 | 團隊 | 價值 |
---|---|---|
2021 年 1 月 1 日 | 團隊1 | 10 |
2021 年 1 月 1 日 | 團隊2 | 10 |
2021 年 1 月 1 日 | Team3 | 10 |
2021 年 1 月 2 日 | 團隊1 | 20 |
2021 年 1 月 2 日 | 團隊2 | 20 |
2021 年 1 月 2 日 | Team3 | 0 |
2021 年 1 月 3 日 | 團隊1 | 0 |
2021 年 1 月 3 日 | 團隊2 | 0 |
2021 年 1 月 3 日 | Team3 | 30 |
在 C# 中:
public class DataEntry
{
public string Date;
public string Teams;
public int Value;
}
public static IEnumerable<DataEntry> GetData()
{
var data = new List<DataEntry>()
{
new DataEntry() { Date = "1/1/2021", Teams = "Team1", Value = 10 },
new DataEntry() { Date = "1/1/2021", Teams = "Team2", Value = 10 },
new DataEntry() { Date = "1/1/2021", Teams = "Team3", Value = 10 },
new DataEntry() { Date = "1/2/2021", Teams = "Team1", Value = 20 },
new DataEntry() { Date = "1/2/2021", Teams = "Team2", Value = 20 },
new DataEntry() { Date = "1/3/2021", Teams = "Team3", Value = 30 },
};
var dates = data.Select(d => d.Date).Distinct().OrderBy(d => d);
var teams = data.Select(d => d.Teams).Distinct().OrderBy(d => d);
foreach (var date in dates)
{
foreach (var team in teams)
{
yield return new DataEntry()
{
Date = date,
Teams = team,
Value = data.SingleOrDefault(d => d.Date == date && d.Teams == team)?.Value ?? 0
};
}
}
}
public static void Main(string[] args)
{
foreach (var d in GetData()) Console.WriteLine($"{d.Date} {d.Teams} {d.Value}");
}
假設您在數據庫中擁有它,那么在那里執行它可能會更容易
SELECT t.Date, d.Teams, IsNull(tt.Value, 0) as Value
FROM (SELECT DISTINCT Date FROM #Table) t
CROSS JOIN (SELECT DISTINCT Teams FROM #Table) d
LEFT JOIN #Table tt
ON t.Date = tt.Date
AND d.Teams = tt.Teams
ORDER BY t.Date, d.Teams
假設您的數據如下所示:
var data = new[]
{
new { Date = "1/1/2021", Team = "Team1", Value = 10 },
new { Date = "1/1/2021", Team = "Team2", Value = 10 },
new { Date = "1/1/2021", Team = "Team3", Value = 10 },
new { Date = "1/2/2021", Team = "Team1", Value = 20 },
new { Date = "1/2/2021", Team = "Team2", Value = 20 },
new { Date = "1/3/2021", Team = "Team3", Value = 30 }
};
然后這將產生你想要的表:
var teams = data.Select(rec => rec.Team).Distinct().OrderBy(team => team).ToArray();
var groupings = data.GroupBy(rec => DateTime.Parse(rec.Date));
var table = groupings.OrderBy(grouping => grouping.Key).SelectMany(grouping =>
{
var dict = grouping.ToDictionary(rec => rec.Team, rec => rec.Value);
return teams.Select(team =>
{
dict.TryGetValue(team, out int value);
return new { Date = grouping.Key, Team = team, Value = value };
});
});
第一條語句按字母順序為您提供所有團隊。 第二條語句按日期對記錄進行分組。 第三個語句按順序遍歷每個日期,查找每個團隊在該日期的值(如果沒有,則使用 0)。
你可以像這樣測試它:
foreach (var row in table)
{
Console.WriteLine(row);
}
Output 是:
{ Date = 1/1/2021 12:00:00 AM, Team = Team1, Value = 10 }
{ Date = 1/1/2021 12:00:00 AM, Team = Team2, Value = 10 }
{ Date = 1/1/2021 12:00:00 AM, Team = Team3, Value = 10 }
{ Date = 1/2/2021 12:00:00 AM, Team = Team1, Value = 20 }
{ Date = 1/2/2021 12:00:00 AM, Team = Team2, Value = 20 }
{ Date = 1/2/2021 12:00:00 AM, Team = Team3, Value = 0 }
{ Date = 1/3/2021 12:00:00 AM, Team = Team1, Value = 0 }
{ Date = 1/3/2021 12:00:00 AM, Team = Team2, Value = 0 }
{ Date = 1/3/2021 12:00:00 AM, Team = Team3, Value = 30 }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.