c# - 我可以使用 LINQ GroupBy 更干净地执行此操作吗?
问题描述
在这个与我的实际问题非常相似的人为示例中,我有一个来自外部源的数据集。来自外部来源的每条记录都采用以下形式:
[Classification] NVARCHAR(32),
[Rank] INT,
[Data] NVARCHAR(1024)
我正在寻找构建一个对象,其中Rank
和Data
被修补到响应对象的单个实例中,该对象包含三个硬编码Classification
值的列表属性,按Rank
.
我有一些可行的方法,但我不禁认为它可以做得更好。这就是我所拥有的:
public static void Main()
{
IEnumerable<GroupingTestRecord> records = new List<GroupingTestRecord>
{
new GroupingTestRecord { Classification = "A", Rank = 1, Data = "A1" },
new GroupingTestRecord { Classification = "A", Rank = 2, Data = "A2" },
new GroupingTestRecord { Classification = "A", Rank = 3, Data = "A3" },
new GroupingTestRecord { Classification = "B", Rank = 1, Data = "B1" },
new GroupingTestRecord { Classification = "B", Rank = 2, Data = "B2" },
new GroupingTestRecord { Classification = "B", Rank = 3, Data = "B3" },
new GroupingTestRecord { Classification = "C", Rank = 1, Data = "C1" },
new GroupingTestRecord { Classification = "C", Rank = 2, Data = "C2" },
new GroupingTestRecord { Classification = "C", Rank = 3, Data = "C3" },
};
GroupTestResult r = new GroupTestResult
{
A = records.Where(i => i.Classification == "A").Select(j => new GroupTestResultItem { Rank = j.Rank, Data = j.Data, }).OrderBy(k => k.Rank),
B = records.Where(i => i.Classification == "B").Select(j => new GroupTestResultItem { Rank = j.Rank, Data = j.Data, }).OrderBy(k => k.Rank),
C = records.Where(i => i.Classification == "C").Select(j => new GroupTestResultItem { Rank = j.Rank, Data = j.Data, }).OrderBy(k => k.Rank),
};
源记录 DTO:
public class GroupingTestRecord
{
public string Classification { get; set; }
public int? Rank { get; set; }
public string Data { get; set; }
}
目标单类:
public class GroupTestResult
{
public IEnumerable<GroupTestResultItem> A { get; set; }
public IEnumerable<GroupTestResultItem> B { get; set; }
public IEnumerable<GroupTestResultItem> C { get; set; }
}
区分子类:
public class GroupTestResultItem
{
public int? Rank { get; set; }
public string Data { get; set; }
}
输出
{
"A":[
{
"Rank":1,
"Data":"A1"
},
{
"Rank":2,
"Data":"A2"
},
{
"Rank":3,
"Data":"A3"
}
],
"B":[
{
"Rank":1,
"Data":"B1"
},
{
"Rank":2,
"Data":"B2"
},
{
"Rank":3,
"Data":"B3"
}
],
"C":[
{
"Rank":1,
"Data":"C1"
},
{
"Rank":2,
"Data":"C2"
},
{
"Rank":3,
"Data":"C3"
}
]
}
有没有更好的方法来实现我的目标?
解决方案
相同的 JSON 输出是在GroupBy
first 上使用Classification
并应用ToDictionary
在结果上实现的IGrouping<string, GroupingTestRecord>.Key
var r = records
.GroupBy(_ => _.Classification)
.ToDictionary(
k => k.Key,
v => v.Select(j => new GroupTestResultItem { Rank = j.Rank, Data = j.Data, }).OrderBy(k => k.Rank).ToArray()
);
var json = JsonConvert.SerializeObject(r);
Console.WriteLine(json);
它应该很容易反序列化到目标单个类(例如在客户端上)
var result = JsonConvert.DeserializeObject<GroupTestResult>(json);
是否可以将顶级结果放入
GroupTestResult
对象中?
从字典中构建结果
var result = new GroupTestResult {
A = r.ContainsKey("A") ? r["A"] : Enumerable.Empty<GroupTestResultItem>();,
B = r.ContainsKey("B") ? r["B"] : Enumerable.Empty<GroupTestResultItem>();,
C = r.ContainsKey("C") ? r["C"] : Enumerable.Empty<GroupTestResultItem>();,
};
推荐阅读
- azure-web-app-service - Azure 应用程序网关支持 Open ID 连接身份验证
- sql - 窗口函数在逻辑标准上增加列
- r - 为什么森林图没有显示置信区间条?
- clang - 使用 clang 预处理器将所有宏声明作为字符串查找?
- user-interface - VS Code 扩展侧边栏不显示/加载
- ios - Xamarin.Forms:iOS 相机不工作,图库工作正常(Android,两者都工作)
- javascript - 如何在同一个按钮上使用 onClick 调用这两个函数?
- c# - 编辑 DataGridTextColumn 或 DataGridComboBoxColumn 时自动完成
- python - 为什么视图路径 /slug:slug/slug:url/ 找不到 django
- symfony - Symfony 5 Phpunit 未定义方法