我有一个数据结构,其中模块包含单元,单元包含节,从模块列表中,我想找到第一个模块,其中至少包含一个单元,其中至少包含一个节,我想对模块、单元和节做些什么。
我最初试着用
modules.Find()
但它只告诉我第一个非空模块是什么,所以我必须查找该单元两次:
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#中做到这一点?