在Ruby中迭代一个块很简单 - 它干净利落地完成并继续执行其余的代码.
另一方面,使用枚举器进行迭代会更加混乱.如果您调用:每个没有块,则返回枚举器.:然后可以在Enumerator上调用next来获取每个下一个迭代值.
然后奇怪的部分 - 当迭代完成时,而不是Enumerator返回nil,它抛出一个异常:"迭代到达结束".结果是它甚至没有返回值.
例如:
test = [ 'test_value' ]
enumerator = test.each
enumerator.next
>> "test_value"
enumerator.next
>> StopIteration: iteration reached at end
Run Code Online (Sandbox Code Playgroud)
这样做的原因是,枚举器可以返回零值吗?答案发生在我身上,因为我发布了这个(所以我要发布它),但似乎一定是这样.
如果是这样,这是处理此类问题的典型方式吗?使用Exception来处理基本上按预期执行的代码似乎很奇怪.
如何Enumerator使用密钥获取-Sorted-字典中的项目?
注意:GetEnumerator()获取Enumerator第一个元素..
但我需要Enumerator使用给定的密钥来获取元素,MoveNext()以便例如使用... 来访问下一个元素...
编辑:或者访问下一个元素的方法......
编辑:我更喜欢const time方法......
谢谢
我有多线程应用程序,我得到这个错误
************** Exception Text **************
System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
at System.Collections.Generic.List`1.Enumerator.MoveNextRare()
at System.Collections.Generic.List`1.Enumerator.MoveNext()
...
Run Code Online (Sandbox Code Playgroud)
我的收藏可能有问题,因为在一个线程上我读取了我的收藏,在另一个线程上我修改了收藏.
public readonly ObservableCollectionThreadSafe<GMapMarker> Markers = new ObservableCollectionThreadSafe<GMapMarker>();
public void problem()
{
foreach (GMapMarker m in Markers)
{
...
}
}
Run Code Online (Sandbox Code Playgroud)
我试图用这段代码锁定集合,但不起作用.
public void problem()
{
lock(Markers)
{
foreach (GMapMarker m in Markers)
{
...
}
}
}
Run Code Online (Sandbox Code Playgroud)
有什么想法来解决这个问题?
因此,Play2.0 Enumeratee页面显示了使用&>或through方法将其更改Enumerator[String]为Enumerator[Int]:的示例:
val toInt: Enumeratee[String,Int] = Enumeratee.map[String]{ s => s.toInt }
val ints: Enumerator[Int] = strings &> toInt
Run Code Online (Sandbox Code Playgroud)
还有一个Enumeratee.grouped枚举器可以从各个元素创建块的枚举器.这似乎工作正常.
但我所看到的是,通常的输入将是Array[Byte](由Enumerator.fromFileand和返回Enumerator.fromStream)的形式.考虑到这一点,我想采取这些Array[Byte]输入并将它们变成一个Enumerator[String],例如每个字符串是一行(以a结尾'\n').线条和Array[Byte]元素的边界通常不匹配.如何编写可以将分块数组转换为分块字符串的枚举器?
目的是在每个行Array[Byte]变为可用时将这些行重新组合回浏览器,并保留不属于完整行的剩余字节,直到下一个输入块出现.
理想情况下,我希望有一个方法给出一个iter: Iteratee[Array[Byte], T]和一个Enumerator[Array[Byte]]会给我一个Enumerator[T],我的T元素被解析iter.
附加信息:我有一点时间来清理我的代码,这是我正在尝试做的一个具体的例子.我有以下迭代检测下一行:
import play.api.libs.iteratee._
type AB = Array[Byte]
def takeWhile(pred: Byte => Boolean): Iteratee[AB, AB] = {
def step(e: Input[AB], acc: AB): …Run Code Online (Sandbox Code Playgroud) 我基本上试图使我的类能够迭代使用foreach.我读了这个教程.MSDN.看起来很直接.但是,当我想第二次迭代时,我遇到了问题.我调试了它; 事实证明它没有调用该Reset()函数.
class A : IEnumerable, IEnumerator
{
int[] data = { 0, 1, 2, 3, 4 };
int position = -1;
public object Current
{
get
{
return data[position];
}
}
public bool MoveNext()
{
position++;
return (position < data.Length);
}
public void Reset()
{
position = -1;
}
public IEnumerator GetEnumerator()
{
return (IEnumerator)this;
}
}
Run Code Online (Sandbox Code Playgroud)
当我运行以下主要功能时; 它从不调用Reset()功能.所以,经过一个循环,我再也无法迭代我的课了.
static void Main(string[] args)
{
A a = new A(); …Run Code Online (Sandbox Code Playgroud) 在Ruby Array类文档中,我经常发现:
如果没有给出块,则返回枚举器.
为什么我不通过一个块#map?我的做法是什么:
[1,2,3,4].map
Run Code Online (Sandbox Code Playgroud)
而不是做:
[1,2,3,4].map{ |e| e * 10 } # => [10, 20, 30, 40]
Run Code Online (Sandbox Code Playgroud)
有人能告诉我一个使用这个枚举器的非常实用的例子吗?
我在Ruby On Rails应用程序中有一个方法,我想同时运行.该方法应该创建一个包含来自站点的报告的zip文件,其中zip中的每个文件都是PDF.从html到PDF的转换有点慢,因此需要多线程.
我想使用5个线程,所以我想我会在线程之间有一个共享的枚举器.每个线程都会从Enumerator中弹出一个值,然后运行do stuff.这就是我认为它会起作用的方式:
t = Zip::OutputStream::write_buffer do |z|
mutex = Mutex.new
gen = Enumerator.new{ |g|
Report.all.includes("employee" => ["boss", "client"], "projects" => {"project_owner" => ["project_team"]}).find_each do |report|
g.yield report
end
}
5.times.map {
Thread.new do
begin
loop do
mutex.synchronize do
@report = gen.next
end
title = @report.title + "_" + @report.id.to_s
title += ".pdf" unless title.end_with?(".pdf")
pdf = PDFKit.new(render_to_string(:template => partial_url, locals: {array: [@report]},
:layout => false)).to_pdf
mutex.synchronize do
z.put_next_entry(title)
z.write(pdf)
end
end
rescue StopIteration
# …Run Code Online (Sandbox Code Playgroud) 比方说,我有两个枚举,enum1而enum2必须通过懒洋洋地迭代(因为他们有副作用).如何构建第三枚举enum3,其中enum3.each{|x| x}就懒洋洋地返回相当于enum1 + enum2?
在我的真实世界用例中,我在两个文件中流式传输,需要流式传输串联.
如果我像这样创建一个Enumertor:
enum = [1,2,3].each => #<Enumerator: [1, 2, 3]:each>
Run Code Online (Sandbox Code Playgroud)
enum是一名调查员.这个对象的目的是什么?我不能这样说:
enum { |i| puts i }
Run Code Online (Sandbox Code Playgroud)
但我可以这样说:
enum.each { |i| puts i }
Run Code Online (Sandbox Code Playgroud)
这似乎是多余的,因为Enumerator是用.each.创建的.它似乎存储了一些有关该each方法的数据.
我不明白这里发生了什么.我确信我们有这个Enumerator类有一些合乎逻辑的原因,但是它能做什么,Array不能呢?我想也许它是Array和其他Enumerables的祖先,但它似乎不是.究竟是什么原因导致存在Enumerator类,以及它将在何种上下文中使用?
我正在寻找一种在Play框架中打印响应体的方法,我有这样的代码:
object AccessLoggingAction extends ActionBuilder[Request] {
def invokeBlock[A](request: Request[A], block: (Request[A]) => Future[Result]) = {
Logger.info(s"""Request:
id=${request.id}
method=${request.method}
uri=${request.uri}
remote-address=${request.remoteAddress}
body=${request.body}
""")
val ret = block(request)
/*
ret.map {result =>
Logger.info(s"""Response:
id=${request.id}
body=${result.body}
""")
}
*/ //TODO: find out how to print result.body (be careful not to consume the enumerator)
ret
}
}
Run Code Online (Sandbox Code Playgroud)
目前,已注释掉的代码无法正常工作,我的意思是,它会打印出来:
Response:
id=1
body=play.api.libs.iteratee.Enumerator$$anon$18@39e6c1a2
Run Code Online (Sandbox Code Playgroud)
所以,我需要找到一种从Enumerator [Array [Byte]]中获取String的方法.我试着通过阅读这篇文章来了解Enumerator的概念:http://mandubian.com/2012/08/27/understanding-play2-iteratees-for-normal-humans/
所以...,如果我理解正确的话:
我不应该在将它转换为String的过程中干掉枚举器.否则,客户端将不会收到任何信息.
让我们假设我弄清楚如何实现T /过滤器机制.但那么......它不会打败Play框架作为非阻塞流式传输框架的目的(因为我会在内存中构建完整的字节数组,然后在其上调用toString,最后记录它)?
那么,记录响应的正确方法是什么?
提前谢谢,拉卡
enumerator ×10
ruby ×5
c# ×3
iterate ×2
scala ×2
.net ×1
dictionary ×1
enumerable ×1
enumeration ×1
exception ×1
foreach ×1
lazy-loading ×1
logging ×1