2016-08-09 30 views

回答

5

这似乎按照我想要的方式工作;

enums.lazy.flat_map{|enum| enum.lazy } 

这是演示。定义这些产生副作用的方法;

def test_enum 
    return enum_for __method__ unless block_given? 
    puts 'hi' 
    yield 1 
    puts 'hi again' 
    yield 2 
end 

def test_enum2 
    return enum_for __method__ unless block_given? 
    puts :a 
    yield :a 
    puts :b 
    yield :b 
end 

concated_enum = [test_enum, test_enum2].lazy.flat_map{|en| en.lazy } 

然后调用下一个结果,显示副作用发生懒惰;

[5] pry(main)> concated_enum.next 
hi 
=> 1 
[6] pry(main)> concated_enum.next 
hi again 
=> 2 
+1

非常感谢'flat_map'解决方案。尽管我们已经验证了flat_map的懒惰,但这并不是我们想到的,将它用作懒惰的附加语句! :) –

+0

该解决方案的缺点是'concated_enum.size'总是返回'nil'。 – skalee

+0

@skalee我认为这是懒惰枚举的缺点;除非你重复它们,否则你永远不会知道它们有多大。它们的大小可能是你迭代多长时间的函数。他们甚至可以是无限的。 –

0

下面是一些code I wrote for fun awhile back懒枚举抛出:

def cat(*args) 
    args = args.to_enum 

    Enumerator.new do |yielder| 
    enum = args.next.lazy 

    loop do 
     begin 
     yielder << enum.next 
     rescue StopIteration 
     enum = args.next.lazy 
     end 
    end 
    end 
end 

你会使用这样的:

enum1 = [1,2,3] 
enum2 = [4,5,6] 
enum3 = cat(enum1, enum2) 

enum3.each do |n| 
    puts n 
end 
# => 1 
# 2 
# 3 
# 4 
# 5 
# 6 

...或者只是:

cat([1,2,3],[4,5,6]).each {|n| puts n }