2015-12-17 132 views
0

我工作了很多的元素的2D網格,我有時需要枚舉這些元素,所以我有一個類,看起來像這樣:有沒有辦法將大小傳遞給`enum_for` /`to_enum`?

class Grid 
    def initialize(width, height) 
    @elements = Array.new(width * height, DEFAULT_ELEMENT) 
    end 

    def each(&block) 
    return enum_for(:each) unless block_given? 

    @elements.each(&block) 

    return self 
    end 
end 

這一直永遠的罰款,但今天才我是否意識到由#each返回的Enumerator不會延遲計算大小。我可以手動定義一個Enumerator,但除了each之外,我還有不少調查員,那樣會很乏味。

所以我想知道是否有像enum_for(:method, lazy_size)這樣的東西,以便我可以寫enum_for(:each width * height)

+2

燦你擴展你的意思是「懶散地計算大小」? – sawa

+2

@sawa'Enumerable#count'必須枚舉整個集合,而'Enumerator#size'試圖計算* lazily *的大小,即不枚舉。 – Stefan

回答

2

你可以傳遞一個塊enum_for計算枚舉的大小:

enum_for(:each) { width * height } 
+0

很明顯...我試着傳遞額外的參數,但那並不奏效。但是,這是紅寶石,通過塊總是訣竅:)謝謝! –

0

如果您計劃支持各種類型枚舉的,可能是你應該考慮實施Enumerable混入

DEFAULT_ELEMENT = ":" 

class Grid 
    include Enumerable 

    def initialize(width, height) 
    @elements = Array.new(width * height, DEFAULT_ELEMENT) 
    end 

    def each 
    @elements.each {|i| yield i} 
    end 

end 


p Grid.new(2,2).map {|i| "#{i}-)"} 
#=> [":-)", ":-)", ":-)", ":-)"] 

p Grid.new(4,6).count 
#=> 24 
+0

這實際上並沒有解決問題。 –

+0

是的,'#count'可以在任何枚舉器上工作,但它是O(n),而不是O(1)。 –

相關問題