Joh*_*lph 15 c# ienumerable f# yield enumerators
我正在学习F#,我真的很喜欢yield!(yield-bang)运算符.不仅因为它的名字,而且它当然也是它的作用.
的yield!操作者基本上可以让你产生序列的所有元素从一个序列的表达.这对于编写枚举器很有用.由于我经常遇到大而复杂的调查员,我对策略很感兴趣,我们可以用它来分解它们,并从简单的枚举器中编写它们.
不幸的是,yield!C#中没有运营商.据我了解,它的作用就像一foreach (var x in source) yield x;本书,但我正在阅读的书(Petricek的真实世界F# - Manning)表明它有更好的表现......
为了在C#中实现类似的构造,我已经探索了多种方式,但是它们都没有像yield!运算符那样简洁,我也不确定它们的复杂性.如果我的BigO号码正确,有人可以提供输入吗?
将枚举器分解为多个私有枚举器,然后从公共枚举器中生成每个元素:
foreach (var x in part1()) yield x
foreach (var x in part2()) yield x
Run Code Online (Sandbox Code Playgroud)
这将有效地导致每个元素的"双倍收益".那是O(2n)吗?(或者可能更糟?)无论如何,使用这种方法阻止我使用yield break;我的任何子部分.
将枚举器分解为多个私有枚举器,然后从公共枚举器中连接所有私有枚举器:
return part1().Concat(part2())
Run Code Online (Sandbox Code Playgroud)
我相信这与上述解决方案没有什么不同,因为它Concat()是按照我上面概述的方式实现的.
还有其他选择吗?
在当前版本的C#中,我认为除了foreach... yield return和之外你还有其他选择Concat.我同意yield!在C#中使用运算符会很好,它会使某些结构更加优雅,但我怀疑这个功能是否会成为"必备"列表,因为我们可以很容易地将其删除.
您可能对此MS研究论文感兴趣,该论文介绍了一种新的yield foreach构造:
IEnumerable<XmlNode> Traverse(XmlNode n)
{
yield return n;
foreach (XmlNode c in n.ChildNodes)
yield foreach Traverse(c);
}
Run Code Online (Sandbox Code Playgroud)
关于复杂性的问题:在两种情况下都是O(n).不使用O(2n),因为它表示与O(n)(线性)相同的复杂度.我认为你不能用当前的C#功能做得更好......
| 归档时间: |
|
| 查看次数: |
4534 次 |
| 最近记录: |