我读过这篇文章,关于可枚举枚举器。map是Enumerable的方法
module Enumerable
def map(*several_variants) ## `*several_variants` [https://stackoverflow.com/questions/28527931/definition-of-ruby-inbuilt-methods][2]
#This is a stub, used for indexing
end
end
class Enumerator # Enumerator class has included Enumerable module Ok fine !!!
include Enumerable # many thing are there ...
end在Array类中:
class Array # Array class has included Enumerable module it means all the instances methods of Enumerable module will expose as the instance methods in Array class !!! Okk
include Enumerable # many thing are there ...
end现在,当我在数组上调用map方法时,我得到了一个Enumerator
[1,2,3,4].map => #<Enumerator: [1, 2, 3, 4]:map> 1:,在上面的#<Enumerator: [1, 2, 3, 4]:map>输出行中,Enumerator是什么?
module Test
def initialize(str)
@str = str
end
def methods_1(str)
p "Hello!!#{str}"
end
end
class MyTest
include Test
include Enumerable
end
my_test = MyTest.new('Ruby')
p "Which class ? : #{my_test}"
my_test.methods_1('Rails')
p my_test.map输出
"Which class ? : #<MyTest:0x000000019e6e38>"
"Hello!!Rails"
#<Enumerator: #<MyTest:0x000000019e6e38 @str="Ruby">:map> 2:,这应该是MyTest类的对象,只有在我没有错的情况下。
3:在这行#<Enumerator: #<MyTest:0x000000019e6e38 @str="Ruby">:map>,Enumerator在这里做什么?
感谢所有的在短时间内明确了这个概念。我想分享一些有用的链接,以便在很大程度上掌握这一概念。
映射、选择和其他可枚举方法
可枚举和枚举器
发布于 2015-02-16 08:21:13
我不认为你的问题是专门针对Enumerable#map的。如果浏览可计数模块,您会发现许多方法(包括map)在给定块时返回一件东西,如果没有给出块,则返回枚举数。假设你写了,
[1,2,3].map.with_index { |x,idx| x+idx } #=> [1,3,5]没有给map块,所以它返回一个枚举数:
enum1 = [1,2,3].map
#=> #<Enumerator: [1, 2, 3]:map>然后将方法索引发送到enum1。
enum2 = enum1.with_index
#=> #<Enumerator: #<Enumerator: [1, 2, 3]:map>:with_index>正如您所看到的,enum2也是一个枚举器,一种“复合枚举器”。
enum2有一个块,所以它的元素通过调用Array#each的方法Enumerator#each传递到块中。
通过将任何枚举数转换为数组,我们可以查看它的内容:
enum2.to_a
#=> [[1, 0], [2, 1], [3, 2]]这显示了each将传递到块中的元素,第一个元素是数组[1, 0],导致块变量x被分配为值1,块变量idx被分配为0。
计算的最后一步由Array#each执行。
enum2.each { |x,idx| x+idx } #=> [1,3,5]Enumerator#with_index的文档(以及map和大多数其他Enumerable方法)表示,当对象被赋予块时返回对象(一般不是枚举器),当没有给块时返回枚举数。然而,正如我刚才所展示的,它在任何情况下都是在产生一个枚举数;当它后面跟着一个块时,它会调用接收方类的each方法来完成它的任务。
是的,您可以在自己的类中使用include Enumerable,但是要使用该模块的方法,还必须为类定义方法each。
枚举器允许我们链接方法,并有效地完成这些工作,而无需在链接之间创建临时数组和其他类似的对象。
我曾经对Enumerable模块是如何出现的进行了如下奇特的描述:
很久以前,一位来自太阳升起之地的非常聪明的Rubyest注意到,他用于数组的许多方法与他用于散列、范围和其他集合的方法非常相似。他看到他可以编写它们,这样唯一的区别就是方法“每个”是如何实现的,所以他把它们都放在一个他称为"可算の“(”枚举“)的模块中,然后在不同类型集合的所有类中添加了”“和一个方法"each”。做完这件事后,他想,"生活は快適です“(”生活是美好的“)。
发布于 2015-02-16 07:49:23
map方法的基本思想是,对于元素的每一次迭代,map都将在块中执行的最后一个表达式的值插入到一个新数组中。执行最后一个元素后,map将返回值的new array。
在你的例子中:
Enumerator只是Ruby中的一个类。当您没有在[1,2,3,4].map上添加一个块时,您已经实例化了它。注意,它与Enumerable不同my_test.classEnumerator和ruby来实例化一个my_test.map对象,发现您已经在类中包含了Enumerable模块。发布于 2015-02-16 07:54:07
map最常见的用法是块,如下所示:
[1, 2, 3, 4].map { |n| n*n }
# => [1, 4, 9, 16]但是,如果您调用map而不传递一个块,它仍然返回一些内容。在本例中,它返回一个Enumerator,它知道原始数组,并且它是一个“映射”类型的数组。它可以用于链接其他Enumerator方法,例如:
[1, 2, 3, 4].map.with_index { |n, idx| "entry #{idx} squared: #{n*n}" }
# => ["entry 0 squared: 1", "entry 1 squared: 4", "entry 2 squared: 9", "entry 3 squared: 16"]您可以阅读更多关于班级的文档,但在实践中,您可能想了解如何更多地使用map块。
https://stackoverflow.com/questions/28536257
复制相似问题