c# - 可以使用一些帮助优化此数据分组
问题描述
已经很长时间了,我正在尝试优化一些代码,所以我不必查看 4 个嵌套的 for 循环。我正在处理一组结构类似这样的数据
[
[
{
Key1: Value1,
...
Key2: [{
...
Key3: {
Key4: {
Key5: Value2,
},
Key6: {
Key7: Value3,
},
...
}
}]
}
...
]
]
为破旧的代表道歉。我无法分享数据的实际样本。我需要的是一个按多个字段分组的集合。目前,代码如下所示
foreach (var collection in response.Property1.Collections)
{
var firstGroups = collection.GroupBy(items => items.Key1);
foreach (var group in firstGroups)
{
var secondGroups = group.GroupBy(items => items.Key2.FirstOrDefault().Key3.Key4.Key5);
foreach(var secondGroup in secondGroups)
{
var thirdGroups= secondGroup.GroupBy(items => items.Key2.FirstOrDefault()?.Key3.Key6.Key7);
foreach(var thirdGroup in thirdGroups)
{
yield return new ResultGroup
{
GroupKey= thirdGroup.Key,
Collection = thirdGroup,
...
};
}
}
}
}
不幸的是,我被源数据困住了。我也没有奢侈地重新映射上游数据以允许在这里进行更好的转换。我真的不喜欢这些嵌套循环,并且对想法持开放态度!
解决方案
我的建议是将每个 foreach 放在一个单独的方法中,并让这些方法相互调用。如果您使用有意义的名称,这将不是问题。
优点:更容易理解每个过程会做什么,更容易对它们进行单元测试,更容易重用和维护。
您从一系列集合开始:
IEnumerable<Libraries> Libraries = ...
foreach (var library in libraries)
{
IEnumerable<Book> books = GetBooks(library);
foreach (var book in books)
yield return book;
}
IEnumerable<Book> GetBooks(Library library)
{
// FirstGroup: make groups of departments in the Library:
IEnumerable<int, Department> departmentGroups = library.GroupBy(...);
IEnumerable<Book> books = GetBooks(departmentGroup)
foreach (var book in books)
yield return book;
}
IEnumerable<Book> GetBooks(IGrouping<int, Department> departmentGroups)
{
// SecondGroup: group the bookcases in the departments by location code
IEnumerable<...> bookCasesInSameLocation = departmentGroup.GroupBy(...);
IEnumerable<Book> books = GetBooks(bookCasesInSameLocation)
foreach (var book in books)
yield return book;
}
依此类推,这也适用于 GroupBy 以外的其他 LINQ 语句
IEnumerable<Book> GetBooks(IEnumerable<...> bookCaseLocations)
{
IEnumerable<...> bookShelves = bookCaseLocations.Where(...)
.Where(...)
.Select(...);
IEnumerable<Book> books = GetBooks(bookShelves)
foreach (var book in books)
yield return book;
}
以此类推,直到最后一级:
IEnumerable<Book> GetBooks(BookShelve bookShelve)
{
foreach (Book book in bookShelve.Books.Where(...).Select(...))
{
yield return book;
}
}
挑战当然是为中间结果定义正确的名称和类。但是恕我直言,如果您找不到合适的名称,您确定您知道每个 GroupBy 和其他 LINQ 语句代表什么吗?
推荐阅读
- javascript - 如何在每个单词后重置 javascript 语音识别
- r - 应用地图或修改后如何在小标题中保留变量类型
- python - 如何始终在交互式 matplotlib 窗口中包含完整的图例/额外的艺术家
- automated-tests - cypress 中的工具提示测试
- html - 使用大型自定义拇指图像扩展输入范围的移动
- php - 按性别和年龄对多维数组进行排序
- php - 如何检查多个日期范围之间的重叠日期?
- windows - Docker 拉未经授权:需要身份验证
- c# - .NET Core 与 .NET Framework,我的代码作为 .NET Core 的一部分工作,但不作为 .NET 框架的一部分,为什么?
- scikit-learn - 如何将一组数字分成两个簇并返回对应索引的两个子集?