使用 if - else if 结构将 foreach 重构为 LINQ
我有这个 foreach 循环:
var includedElements = new HashSet<int>();
foreach(var e in elements)
{
var include = false;
if(isTable(e.Key))
{
if(tables.ContainsKey(e.Key)
{
if(tables[e.Key].Elements
.Any(subElem => shouldBeIncluded(subElem.Key) ) )
{
include = true;
}
}
}
else if(shouldBeIncluded(e.Key))
{
include = true;
}
if(include){
includedElements.Add(e.Key);
DoSomeMoreStuff(e);
}
}
我尝试将其重构为 LINQ:
var query =
from e in elements
where
(
isTable(e.Key)
&& tables.ContainsKey(e.Key)
&& tables[e.Key].Elements
.Any(subElem => shouldBeIncluded(subElem.Key) )
) || (
!isTable(e.Key)
&& shouldBeIncluded(e.Key)
)
select e;
foreach(e in query){
includedElements.Add(e.Key);
DoSomeMoreStuff(e);
}
我不确定的是这里的 or 子句。在我的脑海中,我需要包含 !isTable(e.Key)
来处理外部 if
/else if
结构。
我的重构思路正确吗?这两个代码示例是否产生相同的逻辑功能?
这是一种我只需调用一次 isTable
就可以逃脱的方法吗?正如我现在所拥有的,我需要在 ||
的另一侧将其称为倒置。
I have this foreach loop:
var includedElements = new HashSet<int>();
foreach(var e in elements)
{
var include = false;
if(isTable(e.Key))
{
if(tables.ContainsKey(e.Key)
{
if(tables[e.Key].Elements
.Any(subElem => shouldBeIncluded(subElem.Key) ) )
{
include = true;
}
}
}
else if(shouldBeIncluded(e.Key))
{
include = true;
}
if(include){
includedElements.Add(e.Key);
DoSomeMoreStuff(e);
}
}
I have tried to refactor this to LINQ:
var query =
from e in elements
where
(
isTable(e.Key)
&& tables.ContainsKey(e.Key)
&& tables[e.Key].Elements
.Any(subElem => shouldBeIncluded(subElem.Key) )
) || (
!isTable(e.Key)
&& shouldBeIncluded(e.Key)
)
select e;
foreach(e in query){
includedElements.Add(e.Key);
DoSomeMoreStuff(e);
}
What I'm not sure of is the or clause here. In my head I need to include !isTable(e.Key)
to handle the outer if
/else if
structure.
Am I thinking right with my refactoring? Are these two code examples resulting in the same logical functionality?
Is it a way I can get away with only one call to isTable
? As I have it now I need to call it inverted on the other side of the ||
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
是的你是对的。 if
isTable
没有副作用(除了检查某些内容之外不执行任何操作)并且基于参数是确定性的(因此使用 e.Key 调用它两次总是会产生相同的值)。尽管如此,它可能(它可能是一个过早的优化......谁知道呢?)可能更好地保持它与原始if
更加相似并使用三元运算符 (? :
),这样就不必重新检查isTable
我会补充一点,如果您讨厌三元运算符,您可以使用
let
关键字:缓存 isTable(e.Key)
Yes you are right. This if
isTable
doesn't have side effects (doesn't do anything but check something) and is deterministic based on the parameters (so calling it twice with e.Key always result in the same value). Still it could (it could be a premature optimization... Who knows?) probably be better to keep it more similar to the originalif
and use a ternary operator (? :
) so not to recheckisTable
I'll add that if you hate ternary operators, you could use the
let
keyword:to cache the isTable(e.Key)
你是对的。
else if
暗示if
条件不匹配,因此相当于
which 相当于
which 正是您在 LINQ 中编写的内容。
You are correct. The
else if
implies that theif
condition did not match, sois equivalent to
which is equivalent to
which is exactly what you have written in LINQ.