2015-12-17 65 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)。 –

相关问题