我很好奇为什么ruby返回一个Enumerator而不是一个Array,看起来似乎是一个明显的选择.例如:
'foo'.class
# => String
Run Code Online (Sandbox Code Playgroud)
大多数人认为String是一个字符数组.
'foo'.chars.class
# => Enumerator
Run Code Online (Sandbox Code Playgroud)
那么为什么String #chars会返回一个Enumerable而不是一个Array呢?我假设有人对此进行了大量的思考,并认为Enumerator更合适,但我不明白为什么.
我已经定义了一个派生自TDictionary的集合,需要定义一个应用额外过滤器的自定义枚举器.
我被卡住,因为我无法访问TDictionary FItems数组(它是私有的)所以我无法定义MoveNext方法
您将如何继续重新定义从TDictionary派生的类的过滤枚举器?
这是一个简单的代码来说明我想要做的事情:
TMyItem = class(TObject)
public
IsHidden:Boolean; // The enumerator should not return hidden items
end;
TMyCollection<T:TMyItem> = class(TDictionary<integer,T>)
public
function GetEnumerator:TMyEnumerator<T>; // A value filtered enumerator
type
TMyEnumerator = class(TEnumerator<T>)
private
FDictionary: TMyCollection<integer,T>;
FIndex: Integer;
function GetCurrent: T;
protected
function DoGetCurrent: T; override;
function DoMoveNext: Boolean; override;
public
constructor Create(ADictionary: TMyCollection<integer,T>);
property Current: T read GetCurrent;
function MoveNext: Boolean;
end;
end;
function TMyCollection<T>.TMyEnumerator.MoveNext: Boolean;
begin
// In below code, FIndex is not accessible, so I can't …Run Code Online (Sandbox Code Playgroud) 我在Ruby(1.9.2)中有两个来自两个不同来源(二进制数据)的长数据流.
这两个源以两个枚举器的形式封装.
我想检查两个流是否完全相同.
我有几个解决方案,但两者看起来都很不优雅.
第一个简单地将两者转换为数组:
def equal_streams?(s1, s2)
s1.to_a == s2.to_a
end
Run Code Online (Sandbox Code Playgroud)
这是有效的,但它在内存方面并不是非常高效,特别是如果流有很多信息.
另一种选择是......呃.
def equal_streams?(s1, s2)
s1.each do |e1|
begin
e2 = s2.next
return false unless e1 == e2 # Different element found
rescue StopIteration
return false # s2 has run out of items before s1
end
end
begin
s2.next
rescue StopIteration
# s1 and s2 have run out of elements at the same time; they are equal
return true
end
return false
end
Run Code Online (Sandbox Code Playgroud)
那么,有没有更简单,更优雅的方式呢?
我有一个属性数组如下,
attributes = ["test, 2011", "photo", "198.1 x 198.1 cm", "Photo: Manu PK Full Screen"]
Run Code Online (Sandbox Code Playgroud)
当我这样做时,
artist = attributes[-1].gsub("Photo:")
p artist
Run Code Online (Sandbox Code Playgroud)
我在终端获得以下输出
#<Enumerator: "Photo: Manu PK Full Screen":gsub("Photo:")>
Run Code Online (Sandbox Code Playgroud)
想知道为什么我得到一个枚举器对象作为输出?提前致谢.
编辑:请注意,而不是attributes[-1].gsub("Photo:", ""), I am doing attributes[-1].gsub("Photo:")那么想知道为什么枚举器对象已经返回(我期待一个错误消息)和发生了什么.
Ruby - 1.9.2
Rails - 3.0.7
免责声明:最近在haskell-cafe列表上询问了这个问题.我向任何被双重打扰的人道歉.
所有iteratee-实现包,我知道的(例如iteratee,iterIO和conduit)定义一个enumeratee组合物功能,除了enumerator包.在我看来,这似乎是一个严重的限制,但它实现起来似乎相对简单:
import Data.Enumerator
import Data.Enumerator.Internal
(=$=) :: Monad m
=> Enumeratee a0 a1 m (Step a2 m b) -> Enumeratee a1 a2 m b
-> Enumeratee a0 a2 m b
(=$=) e01 e12 step = Iteratee $ do
step' <- runIteratee $ e12 step
runIteratee . joinI $ e01 step'
Run Code Online (Sandbox Code Playgroud)
这里有一些我想念的东西吗?或者其他一些enumerator不定义枚举组成的原因?
在这个例子中,
[1, 2, 3].each_with_index.map{|i, j| i * j}
# => [0, 2, 6]
Run Code Online (Sandbox Code Playgroud)
我的理解是,由于each_with_index枚举器被链接到map,map行为类似于each_with_index在块内传递索引,并返回一个新数组.
为了这,
[1, 2, 3].map.each_with_index{|i, j| i * j}
# => [0, 2, 6]
Run Code Online (Sandbox Code Playgroud)
我不知道如何解释它.
在这个例子中,
[1, 2, 3, 4].map.find {|i| i == 2}
# => 2
Run Code Online (Sandbox Code Playgroud)
我期待输出[2],假设它map被链接到find,map并将返回一个新数组.
另外,我看到了这个:
[1, 2, 3, 4].find.each_with_object([]){|i, j| j.push(i)}
# => [1]
[1, 2, 3, 4].each_with_object([]).find{|i, j| i == 3}
# => [3, []]
Run Code Online (Sandbox Code Playgroud)
你能让我知道如何解释和理解Ruby中的枚举链吗?
我正在查找这两个类之间的区别,这一点出现在很多答案中,这个博客是来源:http: //javarevisited.blogspot.com/2010/10/difference-between-hashmap-and. HTML
但是我没有完全理解它.有人可以详细说明吗?也许有一个例子?
感谢您的关注!
假设你为下面的代码编写了一个自定义枚举器:
public class School : IEnumerable<Student>
Run Code Online (Sandbox Code Playgroud)
然后在客户端代码中,您执行了以下操作:
static void Main(string[] args)
{
var school = CreateSchoolWithStudents();
var query = from student in school
where student.Name.StartsWith("S")
select student;
Debugger.Break();
}
private static School CreateSchoolWithStudents()
{
return new School
{
new Student { Name = "Sathyaish" },
new Student { Name = "John" },
new Student { Name = "Carol" },
new Student { Name = "Peter" }
};
}
Run Code Online (Sandbox Code Playgroud)
然后,在类的MoveNext方法实现上设置一个断点StudentEnumerator.
然后,当您运行代码并且在构造查询/ IEnumerable之后调试器中断,并且您Results View在下面显示的图片中展开了类似内容时,Visual Studio如何评估序列而不会破坏其枚举器MoveNext …
在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来处理基本上按预期执行的代码似乎很奇怪.
我在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) enumerator ×10
ruby ×6
arrays ×1
c# ×1
delphi ×1
exception ×1
hashmap ×1
hashtable ×1
haskell ×1
ienumerator ×1
iterator ×1
java ×1
lazy-loading ×1
linq ×1
list ×1
tdictionary ×1