2016-08-09 72 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 }