Ruby枚举器链接

前端之家收集整理的这篇文章主要介绍了Ruby枚举器链接前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在这个例子中,
[1,2,3].each_with_index.map{|i,j| i * j}
# => [0,6]

我的理解是,由于each_with_index枚举器被链接到map,map通过在块内传递索引来表现得像each_with_index,并返回一个新数组.

为了这,

[1,3].map.each_with_index{|i,6]

我不确定如何解释它.

在这个例子中,3,4].map.find {|i| i == 2} # => 2

我期望输出为[2],假设地图被链接到查找,并且map将返回一个新数组.

另外,我看到了这个:

[1,4].find.each_with_object([]){|i,j| j.push(i)}
# => [1]

[1,4].each_with_object([]).find{|i,j| i == 3}
# => [3,[]]

你能让我知道如何解释和理解Ruby中的枚举链吗?

解决方法

您可能会发现打破这些表达式并使用IRB或PRY来查看Ruby正在做什么很有用.让我们从:
[1,3].each_with_index.map { |i,j| i*j }

enum1 = [1,3].each_with_index
  #=> #<Enumerator: [1,3]:each_with_index>

我们可以使用Enumerable#to_a(或Enumerable#entries)将enum1转换为数组,以查看它将传递给下一个枚举器(或者如果有一个块):

enum1.to_a
  #=> [[1,0],[2,1],[3,2]]

这并不奇怪.但是enum1没有块.相反,我们发送方法Enumerable#map

enum2 = enum1.map
  #=> #<Enumerator: #<Enumerator: [1,3]:each_with_index>:map>

您可能会将此视为一种“复合”枚举器.这个枚举器确实有一个块,所以将它转换为一个数组将确认它会像enum1那样将相同的元素传递给块:

enum2.to_a
  #=> [[1,2]]

我们看到数组[1,0]是enum2传入块的第一个元素. “消歧”应用于此数组,以便为​​块变量分配值:

i => 1
j => 0

也就是说,Ruby正在设置:

i,j = [1,0]

我们现在可以通过向块发送每个方法调用enum2:

enum2.each { |i,j| i*j }
  #=> [0,6]

接下来考虑:

[1,3].map.each_with_index { |i,j| i*j }

我们有:

enum3 = [1,3].map
  #=> #<Enumerator: [1,3]:map>
enum3.to_a
  #=> [1,3]
enum4 = enum3.each_with_index
  #=> #<Enumerator: #<Enumerator: [1,3]:map>:each_with_index>
enum4.to_a
  #=> [[1,2]]
enum4.each { |i,6]

由于enum2和enum4将相同的元素传递给块,我们看到这只是做同样事情的两种方式.

这是第三个等价链:

[1,3].map.with_index { |i,3]
enum5 = enum3.with_index
  #=> #<Enumerator: #<Enumerator: [1,3]:map>:with_index>
enum5.to_a
  #=> [[1,2]]
enum5.each { |i,6]

为了更进一步,假设我们有:

[1,3].select.with_index.with_object({}) { |(i,j),h| ... }

我们有:

enum6 = [1,3].select
  #=> #<Enumerator: [1,3]:select>
enum6.to_a
  #=> [1,3]
enum7 = enum6.with_index
  #=> #<Enumerator: #<Enumerator: [1,3]:select>:with_index>
enum7.to_a
  #=> [[1,2]]
enum8 = enum7.with_object({})
  #=> #<Enumerator: #<Enumerator: #<Enumerator: [1,3]:
  #     select>:with_index>:with_object({})>
enum8.to_a
  #=> [[[1,{}],[[2,[[3,2],{}]]

第一个元素enum8进入块是数组:

(i,h = [[1,{}]

然后应用消歧来为块变量赋值:

i => 1
j => 0
h => {}

请注意,enum8显示了在enum8.to_a的三个元素中的每个元素中传递的空哈希,但当然这仅仅是因为Ruby在传入第一个元素后不知道哈希的样子.

猜你在找的Ruby相关文章