为什么在ruby中使用枚举器
我偶然发现了这样的例子:为什么在ruby中使用枚举器,ruby,Ruby,我偶然发现了这样的例子: file = "./path" var = Enumerator.new do |y| CSV.foreach(file) do |row| y.yield(row) end end 问题是,为什么要在枚举器中存储任何类型的数据,而不是数组?上述内容与以下内容在行为上有何区别: file = "./path" var = [] CSV.foreach(file) do |row| var << row end 那么
file = "./path"
var = Enumerator.new do |y|
CSV.foreach(file) do |row|
y.yield(row)
end
end
问题是,为什么要在枚举器中存储任何类型的数据,而不是数组?上述内容与以下内容在行为上有何区别:
file = "./path"
var = []
CSV.foreach(file) do |row|
var << row
end
那么这种构造的优缺点是什么呢?一般来说,迭代器可以用来惰性地生成一系列对象。 这是创建惰性枚举的主要优势,而创建项集合的效率要高得多 例如,如果您的枚举器循环仅迭代300万项中的前5项,那么这就是所有收益,并且您没有首先在内部构建100万项的集合 因此,您不需要加载所有300万项,因为您的被调用函数可以继续并执行其余代码 迭代器是返回序列的方法 有时序列甚至可能是无限的 它将延迟求值的函数编程概念引入Ruby,至少对于枚举是这样
返回集合和返回集合生成器之间存在巨大差异 通常,迭代器可用于惰性地生成对象序列。 这是创建惰性枚举的主要优势,而创建项集合的效率要高得多 例如,如果您的枚举器循环仅迭代300万项中的前5项,那么这就是所有收益,并且您没有首先在内部构建100万项的集合 因此,您不需要加载所有300万项,因为您的被调用函数可以继续并执行其余代码 迭代器是返回序列的方法 有时序列甚至可能是无限的 它将延迟求值的函数编程概念引入Ruby,至少对于枚举是这样
返回集合和返回集合生成器之间存在巨大差异 也可以看到代码的不同之处,在循环中添加一个
put
seq = (1..3)
enum = Enumerator.new do |y|
seq.each do |i|
puts "Grabbing #{i} with enumerator"
y.yield(i)
end
end
enum.each { |i| puts "Taken #{i} from enumerator" }
# Grabbing 1 with enumerator
# Taken 1 from enumerator
# Grabbing 2 with enumerator
# Taken 2 from enumerator
# Grabbing 3 with enumerator
# Taken 3 from enumerator
array = []
seq.each do |i|
puts "Grabbing #{i} with array"
array << i
end
array.each { |i| puts "Taken #{i} from array" }
# Grabbing 1 with array
# Grabbing 2 with array
# Grabbing 3 with array
# Taken 1 from array
# Taken 2 from array
# Taken 3 from array
处理巨大或无限序列时,差异非常重要。也请参见代码的差异添加
将放入循环中
seq = (1..3)
enum = Enumerator.new do |y|
seq.each do |i|
puts "Grabbing #{i} with enumerator"
y.yield(i)
end
end
enum.each { |i| puts "Taken #{i} from enumerator" }
# Grabbing 1 with enumerator
# Taken 1 from enumerator
# Grabbing 2 with enumerator
# Taken 2 from enumerator
# Grabbing 3 with enumerator
# Taken 3 from enumerator
array = []
seq.each do |i|
puts "Grabbing #{i} with array"
array << i
end
array.each { |i| puts "Taken #{i} from array" }
# Grabbing 1 with array
# Grabbing 2 with array
# Grabbing 3 with array
# Taken 1 from array
# Taken 2 from array
# Taken 3 from array
在处理大型或无限序列时,差异非常重要。目前这是正确的,但请注意,惰性枚举数是后来添加的。枚举数没有它们就存在。@sawa惰性枚举数功能是枚举数
和枚举数
之间的适配器,可以轻松支持枚举数的惰性。现在是这样,但请注意,惰性枚举数是后来添加的。枚举数不存在。@sawa惰性枚举数功能是枚举数
和枚举数
之间的适配器,可轻松支持枚举数的惰性。
# infinite number sequence
numbers = Enumerator.new do |y|
n = 0
loop { y.yield(n += 1) }
end
puts numbers.take(3).join(', ')
# 1, 2, 3