Enumerator::Yielder#yield 方法什么时候有用?
问题“yield 这个词的含义”提到了 Enumerator::Yielder #yield 方法。我以前没有使用过它,不知道在什么情况下它会有用。
当您想要创建无限的项目列表(例如埃拉托斯特尼筛法)以及需要使用外部迭代器时,它主要有用吗?
The question "Meaning of the word yield" mentions the Enumerator::Yielder#yield
method. I haven't used it before, and wonder under what circumstances it would be useful.
Is it mainly useful when you want to create an infinite list of items, such as the Sieve of Eratosthenes, and when you need to use an external iterator?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
“如何创建无限可枚举的 Times?”演讲关于构造和惰性迭代器,但我最喜欢的用法是用附加功能包装现有的 Enumerable(任何可枚举的,而不需要知道它到底是什么,无论它是否是无限的等)。
一个简单的例子是实现
each_with_index
方法(或者更一般地说,with_index
方法):扩展到核心库中尚未实现的内容,例如循环分配值将给定数组分配给每个可枚举元素(例如,用于为表行着色):
重点是这些方法返回一个
Enumerator
,然后将其与常用的 Enumerable 方法(例如select)结合使用
、映射
、注入
等。"How to create an infinite enumerable of Times?" talks about constructing and lazy iterators, but my favorite usage is wrapping an existing Enumerable with additional functionality (any enumerable, without needing to know what it really is, whether it's infinite or not etc).
A trivial example would be implementing the
each_with_index
method (or, more generally,with_index
method):Extending to something not already implemented in the core library, such as cyclically assigning value from a given array to each enumerable element (say, for coloring table rows):
The whole point is that these methods return an
Enumerator
, which you then combine with the usual Enumerable methods, such asselect
,map
,inject
etc.例如,您可以使用它来构建内联的 Rack 响应主体,而无需创建类。
Enumerator
也可以“由外向内”工作 - 您调用Enumerator#each
,它会调用枚举器上的next
并按顺序返回每个值。例如,您可以使 Rack 响应正文返回数字序列:For example you can use it to construct Rack response bodies inline, without creating classes. An
Enumerator
can also work "outside-in" - you callEnumerator#each
which callsnext
on the enumerator and returns every value in sequence. For example, you can make a Rack response body returning a sequence of numbers:由于 Mladen 提到获得其他答案,我想我应该举一个我今天早些时候在编写一个应用程序时所做的事情的例子,该应用程序将从多个物理设备接收数据,分析数据并连接相关数据(我们从多个设备看到) 。这是一个长期运行的应用程序,如果我从不丢弃数据(例如,至少一天前没有更新),那么它会变得无限大。
在过去,我会做这样的事情:
并使用随机数来完成此操作。然而,这并不是纯粹的确定性。我知道它大约每 300 次评估(即秒)运行一次,但不会恰好每 300 次运行一次。
我之前写的内容如下所示:
我可以将
delete_old_stuff if rand(300) == 0
替换为counter.next
现在,我确信还有更多执行此操作的有效或预制方法,但由于您的问题和链接的问题而激发了使用
Enumerator::Yielder#yield
,这就是我想出的方法。Since Mladen mentioned getting other answers, I thought I would give an example of something I just did earlier today while writing an application that will receive data from multiple physical devices, analyze the data, and connect related data (that we see from multiple devices). This is a long-running application, and if I never threw away data (say, at least a day old with no updates), then it would grow infinitely large.
In the past, I would have done something like this:
and accomplish this using random numbers. However, this is not purely deterministic. I know that it will run approximately once every 300 evaluations (i.e. seconds), but it won't be exactly once every 300 times.
What I wrote up earlier looks like this:
and I can replace
delete_old_stuff if rand(300) == 0
withcounter.next
Now, I'm sure there is a more efficient or pre-made way of doing this, but being sparked to play with
Enumerator::Yielder#yield
by your question and the linked question, this is what I came up with.当您想要枚举多个对象,但 flat_map 不合适,并且您希望将枚举与另一个操作链接起来时,它似乎很有用:
It seems to be useful when you have multiple objects you want to enumerate over, but flat_map isn't suitable, and you want to chain the enumeration with another action: