我在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)
那么,有没有更简单,更优雅的方式呢?
链接each_slice和to_a混淆我.我知道它each_slice是Enumerable的成员,因此可以在数组之类的可枚举对象上调用,并chars返回一个字符数组.
我也知道each_slice将数组分成n个元素,在下面的例子中为2.如果没有给出块each_slice,则它返回一个Enumerator对象.
'186A08'.chars.each_slice(2).to_a
Run Code Online (Sandbox Code Playgroud)
但是,to_a如果each_slice已经将数组分组为n个元素,为什么我们必须调用枚举器对象?为什么ruby只评估枚举器对象是什么(这是n个元素的集合)?
我可以写一个简短的例子来验证内部to_a的Enumerable调用each.这里是:
class MyFooClass
include Enumerable
def initialize
@members = [1, 2, 3]
end
def each
puts "each is now called"
@members.each{ |m| yield(m) }
end
end
a = MyFooClass.new
puts "let us convert to array"
g = a.to_a
Run Code Online (Sandbox Code Playgroud)
输出是:
let us convert to array
each is now called
Run Code Online (Sandbox Code Playgroud)
请注意,each它不是成员Enumerable,但是to_a.此外,如果我each从我的类中删除定义,然后代码崩溃与以下消息:
in `to_a': undefined method `each' for #<MyFooClass:0x997c1ac @members=[1, 2, 3]> (NoMethodError)
Run Code Online (Sandbox Code Playgroud)
我想知道是否有关于此的Ruby官方文档,这将记录to_a(在其成员中Enumerable)通过each …