在Ruby中,返回一个可枚举的'是什么意思?

时间:2015-04-23 14:22:28

标签: ruby

我试图理解以下Ruby代码:

required=#{ value1 != value2}

(作为参考,digits.each_with_index.inject(0) do |decimal, (digit, index)| decimal + digit * 2**index end 是一个返回数组的方法,其中每个元素都是一个整数)。

令我困惑的代码部分是digits。我知道.each_with_index.inject(0)方法的作用,我知道each_with_index方法的作用,但我不确定两者的链接是如何工作的。到底发生了什么?

我试着看一下inject的文档,我猜我遇到问题的部分如下:"如果没有给出阻止,则返回一个枚举器。"

我想所有这一切归结为什么是一个普查员?

2 个答案:

答案 0 :(得分:2)

您可以循环使用Enumerable。它包含在Array,Set等中。

来自文档:http://ruby-doc.org/core-2.2.2/Enumerable.html

  

Enumerable mixin提供了几个集合类   遍历和搜索方法,并具有排序的能力。该   class必须提供一个方法,它产生连续的成员   集合。如果使用了Enumerable#max,#min或#sort,则为对象   在集合中还必须实现一个有意义的< =>运营商,作为   这些方法依赖于集合成员之间的排序。

您可以稍后使用枚举器来迭代: http://ruby-doc.org/core-2.1.5/Enumerator.html Enumerator是一个包装类,包含Enumarable的所有方法

在您的示例代码中,您将默认值0注入each_with_index循环,因此在第一个循环decimal等于0时,digit是数组和索引的第一个值第二次循环时,decimal设置为第一次传递的返回值,digit是第二个数组值,index是1。

例如:

digits = [20,30,40]

循环中的第一次:decimal = 0,digit = 20,index = 0.然后返回20.

循环中的第二次:decimal = 20,digit = 30,index = 1.然后返回80。

循环中第三次:decimal = 80,digit = 40,index = 2。然后返回240。

所以这个块返回240。

答案 1 :(得分:1)

Enumerator抽象了枚举的概念,以便您可以使用所有方便的Enumerable方法,而无需关心底层数据结构。

例如,您可以使用枚举器来创建一个类似于无限数组的对象:

squares = Enumerator.new do |yielder|
  x = 1
  loop do
    yielder << x ** 2
    x += 1
  end
end

squares.take(10)
# [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
squares.count
# don't wait up for this one!

关于枚举器的一个很酷的事情是它们本身是可枚举的,如果你不给它们一个块,大多数Enumerable方法都会返回枚举器。这是允许您链接方法调用以获得一个大枚举器的原因。

以下是我对代码each_with_index的编码方式,以便它可以很好地链接:

class Array
  def my_each_with_index &blk
    e = Enumerator.new do |yielder|
      i = 0
      each do |x|
        yielder << [x, i]
        i += 1
      end
    end

    return e unless blk
    e.each(&blk)
  end
end

[3,2,1].my_each_with_index { |x, i| puts "#{i}: #{x}" }
# 0: 3
# 1: 2
# 3: 1

首先,我们创建一个枚举器,描述如何使用索引进行枚举。如果没有给出块,我们只返回枚举器。否则,我们告诉枚举器使用块枚举(each做什么)。