我试图理解以下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
的文档,我猜我遇到问题的部分如下:"如果没有给出阻止,则返回一个枚举器。"
我想所有这一切归结为什么是一个普查员?
答案 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
做什么)。