Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 如何计算迭代器调用yield的次数?_Ruby_Iterator_Yield - Fatal编程技术网

Ruby 如何计算迭代器调用yield的次数?

Ruby 如何计算迭代器调用yield的次数?,ruby,iterator,yield,Ruby,Iterator,Yield,我有一个方法,foo,可以生成对象。我想数一数它产生的物体的数量 我有 def total_foo count = 0 foo { |f| count += 1} count end 但可能有更好的办法。对这位新红宝石手有什么想法吗 以下是foo的定义(它是Rails中的一个助手方法): 假设您只关心foo的副作用,您可以让foo本身计算迭代次数: def foo(resource=@resource) count = 0 resource.thingies.each do

我有一个方法,
foo
,可以生成对象。我想数一数它产生的物体的数量

我有

def total_foo
  count = 0
  foo { |f| count += 1}
  count
end
但可能有更好的办法。对这位新红宝石手有什么想法吗

以下是
foo
的定义(它是Rails中的一个助手方法):


假设您只关心
foo
的副作用,您可以让
foo
本身计算迭代次数:

def foo(resource=@resource)
  count = 0
  resource.thingies.each do |thingy|
    bar(thingy) do |b|
      count += 1
      yield b
    end  # bar also yields objects
  end
  count
end
然后:

count = foo { |f| whatever... }
如果选择,也可以忽略返回值,因此只需:

foo { |f| whatever... }
万一你不在乎计数是多少


根据更大的背景,可能有更好的方法来处理所有这些问题。

如果您只关心
foo
的副作用,您可以让
foo
本身计算迭代次数:

def foo(resource=@resource)
  count = 0
  resource.thingies.each do |thingy|
    bar(thingy) do |b|
      count += 1
      yield b
    end  # bar also yields objects
  end
  count
end
然后:

count = foo { |f| whatever... }
如果选择,也可以忽略返回值,因此只需:

foo { |f| whatever... }
万一你不在乎计数是多少


根据更大的上下文,可能有更好的方法来处理所有这些问题。

任何调用
yield
的方法都可以用来构建一个对象,您可以通过该方法在其上调用该对象。请记住,当您调用
count
时,迭代器实际上是执行的,因此它应该没有副作用!下面是一个模拟您的场景的可运行示例:

@resources = [[1,2], [3,4]]

def foo(resources = @resources)
  resources.each do |thingy|
    thingy.each { |b| yield b }
  end
end

foo { |i| puts i }
# Output:
# 1
# 2
# 3
# 4

to_enum(:foo).count
# => 4
您可以将参数传递给
foo

to_enum(:foo, [[5,6]]).count
# => 2
或者,您可以定义
foo
来返回
枚举数,当它在没有块的情况下被调用时,这就是stdlib迭代器的工作方式:

def foo(resources = @resources)

  return to_enum(__method__, resources) unless block_given?

  resources.each do |thingy|
    thingy.each { |b| yield b }
  end
end

foo.count
# => 4

foo([[1,2]]).count
# => 2

foo([[1,2]]) { |i| puts i }
# Output:
# 1
# 2
您可以将一个块传递到
到_enum
,当您调用
枚举器以返回值时调用该块:

def foo(resources = @resources)
  unless block_given?
    return to_enum(__method__, resources) do
      resources.map(&:size).reduce(:+) # thanks to @Ajedi32
    end
  end

  resources.each do |thingy|
    thingy.each { |b| yield b }
  end
end

foo.size
# => 4

foo([]).size
# => 0

在这种情况下,使用
size
count
稍微快一点,您的里程数可能会有所不同。

任何调用
yield
的方法都可以用来构建一个对象,您可以通过该方法在该对象上进行调用。请记住,当您调用
count
时,迭代器实际上是执行的,因此它应该没有副作用!下面是一个模拟您的场景的可运行示例:

@resources = [[1,2], [3,4]]

def foo(resources = @resources)
  resources.each do |thingy|
    thingy.each { |b| yield b }
  end
end

foo { |i| puts i }
# Output:
# 1
# 2
# 3
# 4

to_enum(:foo).count
# => 4
您可以将参数传递给
foo

to_enum(:foo, [[5,6]]).count
# => 2
或者,您可以定义
foo
来返回
枚举数,当它在没有块的情况下被调用时,这就是stdlib迭代器的工作方式:

def foo(resources = @resources)

  return to_enum(__method__, resources) unless block_given?

  resources.each do |thingy|
    thingy.each { |b| yield b }
  end
end

foo.count
# => 4

foo([[1,2]]).count
# => 2

foo([[1,2]]) { |i| puts i }
# Output:
# 1
# 2
您可以将一个块传递到
到_enum
,当您调用
枚举器以返回值时调用该块:

def foo(resources = @resources)
  unless block_given?
    return to_enum(__method__, resources) do
      resources.map(&:size).reduce(:+) # thanks to @Ajedi32
    end
  end

  resources.each do |thingy|
    thingy.each { |b| yield b }
  end
end

foo.size
# => 4

foo([]).size
# => 0


在这种情况下,使用
size
count
稍微快一点,您的里程数可能会有所不同。

如何定义
foo
呢?您现在拥有的东西有什么问题?@akonsu它可以工作,但我想知道是否有更好的Ruby方法。例如,
foo.count
@Dennis嗯,我的意思是这是一个清晰易懂的代码。尽管如此,如果您只需要这些对象的计数,为什么要生成所有这些对象呢?但这可能超出了问题的范围。@akonsu
foo
也在其他地方被调用,尽管我可以重写它以避免屈服。但是,如果你不能改变方法的行为,这是计算收益率的最佳选择吗?
foo
是如何定义的?你现在拥有的有什么问题吗?@akonsu它可以工作,但我想知道是否有更好的Ruby方法来做这件事。例如,
foo.count
@Dennis嗯,我的意思是这是一个清晰易懂的代码。尽管如此,如果您只需要这些对象的计数,为什么要生成所有这些对象呢?但这可能超出了问题的范围。@akonsu
foo
也在其他地方被调用,尽管我可以重写它以避免屈服。但是,如果你不能改变方法的行为,这是计算收益率的最佳选择吗?这可能有效,但我发现它比我现在拥有的更混乱。虽然我可以重命名
foo
,以更清楚地表明它会产生一些结果并返回一个计数。@丹尼斯,我可以理解。正如我提到的,它确实取决于上下文。我展示的内容将您想要的关于
foo
的所有内容封装在
foo
的定义中。但这可能比其他选择更冗长。根据
bar
thingies
是什么,可能有更好的方法来完成整个过程:这可能行得通,但我发现它比我现在拥有的更混乱。虽然我可以重命名
foo
,以更清楚地表明它会产生一些结果并返回一个计数。@丹尼斯,我可以理解。正如我提到的,它确实取决于上下文。我展示的内容将您想要的关于
foo
的所有内容封装在
foo
的定义中。但这可能比其他选择更冗长。根据
bar
thingies
是什么,可能有更好的方法来完成整个过程:如何将参数传递给
foo
?@akonsu只需将附加参数传递给
to_enum
方法。文档中说“参数……将在方法中传递给项本身”。这很混乱,是什么项?你知道他们在说什么吗?@akonsu查看Ruby 2.1的文档,应该会更清楚。@AJED32感谢您的编辑,但在看到它之后,我意识到在本例中“大小”块没有真正意义,关键是不要迭代枚举来计算大小。如何将参数传递给
foo
?@akonsu只需将附加参数传递给
to_enum
方法。文档中说“参数……将在方法中传递给项本身。”这让人困惑,什么项?你知道他们在说什么吗?@akonsu查看Ruby 2.1的文档,应该会更清楚。@AJED32感谢您的编辑,但在看到它之后,我意识到在这种情况下,“大小”块没有真正意义,关键是不要迭代枚举来计算大小。