c# - 同时查找和映射
问题描述
我有一个数据结构,其中模块包含单元,单元包含部分,并且从模块列表中,我想找到包含至少一个单元的第一个模块,该单元包含至少一个部分,并且我想对该模块做一些事情,单位和部分。
我最初尝试使用modules.Find()
它,但它只告诉我第一个非空模块是什么,所以我必须查找 Unit 两次:
var module = modules.Find(m => m.Units.Exists(u => u.Sections.Count > 0));
if (module == null)
{
throw new Exception("there are no non-empty modules");
}
var unit = module.Units.Find(u => u.Sections.Count > 0);
var section = unit.Sections.First();
doSomeStuff(module, unit, section);
我最终编写了自己的函数来做到这一点:
private Tuple<Module, Unit, Section> getFirstModuleWithVisibleSection(List<Module> modules)
{
foreach (var module in modules)
{
foreach (var unit in module.Units)
{
var section = unit.Sections.FirstOrDefault();
if (section != null)
{
return new Tuple<Module, Unit, Section>(module, unit, section);
}
}
}
return null;
}
...
var res = getFirstModuleWithVisibleSection(modules);
if (res == null)
{
throw new Exception("no visible modules");
}
var module = res.Item1;
var unit = res.Item2;
var section = res.Item3;
doSomething(module, unit, section);
这是有效的,但它比我希望的要冗长。
我更习惯于 OCaml,我会在其中使用List.find_map
,这就像find
,除了不是返回 true/false 而是返回 null 或 not-null,它返回第一个 not-null。在 C# 中,它看起来像这样:
var (module, unit, section) =
modules.FindMap(module =>
module.Units.FindMap(unit =>
{
var section = unit.Sections.FirstOrDefault();
if (section == null)
{
return null;
}
return (module, unit, section);
}));
有没有办法在 C# 中做到这一点?
解决方案
关于什么:
var query = from m in modules
from u in m.Units
let s = u.Sections.FirstOrDefault()
where s != null
select new
{
m,
u,
s
};
var item = query.FirstOrDefault();
推荐阅读
- mysql - SQL将文本中价格的数据库列转换为数字
- r - 根据代码和日期过滤数据
- java - 如何在 Spring 框架中实现服务器和客户端之间的快速通信?
- c# - 数据插入 Excel 文件
- javascript - 不能在three.js中播放透明webm?
- zurb-foundation - 切换菜单 - 动画高度
- php - 全新安装中未找到类“类‘表单’”
- sql - Qliksense 中的 SQL 逻辑
- javascript - async await 返回一个 Promise 而不是一个值
- shieldui - FieldType.Number 将编辑值限制为 100,任何超过 100 的值都会自动更改为 100