首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何理解#map方法的核心概念

如何理解#map方法的核心概念
EN

Stack Overflow用户
提问于 2015-02-16 07:14:47
回答 3查看 224关注 0票数 2

我读过这篇文章,关于可枚举枚举器mapEnumerable的方法

代码语言:javascript
复制
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类中:

代码语言:javascript
复制
 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

代码语言:javascript
复制
[1,2,3,4].map   => #<Enumerator: [1, 2, 3, 4]:map> 

1:,在上面的#<Enumerator: [1, 2, 3, 4]:map>输出行中,Enumerator是什么?

代码语言:javascript
复制
 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

输出

代码语言:javascript
复制
"Which class ? : #<MyTest:0x000000019e6e38>"
"Hello!!Rails"
#<Enumerator: #<MyTest:0x000000019e6e38 @str="Ruby">:map> 

2:,这应该是MyTest类的对象,只有在我没有错的情况下。

3:在这行#<Enumerator: #<MyTest:0x000000019e6e38 @str="Ruby">:map>Enumerator在这里做什么?

感谢所有的在短时间内明确了这个概念。我想分享一些有用的链接,以便在很大程度上掌握这一概念。

映射、选择和其他可枚举方法

在Ruby中,“map”方法是做什么的?

可枚举和枚举器

Ruby技巧,使您的代码更有趣,更少可读性

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-02-16 08:21:13

我不认为你的问题是专门针对Enumerable#map的。如果浏览可计数模块,您会发现许多方法(包括map)在给定块时返回一件东西,如果没有给出块,则返回枚举数。假设你写了,

代码语言:javascript
复制
[1,2,3].map.with_index { |x,idx| x+idx } #=> [1,3,5]

没有给map块,所以它返回一个枚举数:

代码语言:javascript
复制
enum1 = [1,2,3].map
  #=> #<Enumerator: [1, 2, 3]:map>

然后将方法索引发送到enum1

代码语言:javascript
复制
enum2 = enum1.with_index
  #=> #<Enumerator: #<Enumerator: [1, 2, 3]:map>:with_index>

正如您所看到的,enum2也是一个枚举器,一种“复合枚举器”。

enum2有一个块,所以它的元素通过调用Array#each的方法Enumerator#each传递到块中。

通过将任何枚举数转换为数组,我们可以查看它的内容:

代码语言:javascript
复制
enum2.to_a
  #=> [[1, 0], [2, 1], [3, 2]]

这显示了each将传递到块中的元素,第一个元素是数组[1, 0],导致块变量x被分配为值1,块变量idx被分配为0

计算的最后一步由Array#each执行。

代码语言:javascript
复制
enum2.each { |x,idx| x+idx } #=> [1,3,5]

Enumerator#with_index的文档(以及map和大多数其他Enumerable方法)表示,当对象被赋予块时返回对象(一般不是枚举器),当没有给块时返回枚举数。然而,正如我刚才所展示的,它在任何情况下都是在产生一个枚举数;当它后面跟着一个块时,它会调用接收方类的each方法来完成它的任务。

是的,您可以在自己的类中使用include Enumerable,但是要使用该模块的方法,还必须为类定义方法each

枚举器允许我们链接方法,并有效地完成这些工作,而无需在链接之间创建临时数组和其他类似的对象。

我曾经对Enumerable模块是如何出现的进行了如下奇特的描述:

很久以前,一位来自太阳升起之地的非常聪明的Rubyest注意到,他用于数组的许多方法与他用于散列、范围和其他集合的方法非常相似。他看到他可以编写它们,这样唯一的区别就是方法“每个”是如何实现的,所以他把它们都放在一个他称为"可算の“(”枚举“)的模块中,然后在不同类型集合的所有类中添加了”“和一个方法"each”。做完这件事后,他想,"生活は快適です“(”生活是美好的“)。

票数 1
EN

Stack Overflow用户

发布于 2015-02-16 07:49:23

map方法的基本思想是,对于元素的每一次迭代,map都将在块中执行的最后一个表达式的值插入到一个新数组中。执行最后一个元素后,map将返回值的new array

在你的例子中:

  1. Enumerator只是Ruby中的一个类。当您没有在[1,2,3,4].map上添加一个块时,您已经实例化了它。注意,它与Enumerable不同
  2. 是的,这是你的MyTest课程。如果您喜欢测试它,请执行my_test.class
  3. 您只是通过执行Enumerator和ruby来实例化一个my_test.map对象,发现您已经在类中包含了Enumerable模块。
票数 0
EN

Stack Overflow用户

发布于 2015-02-16 07:54:07

map最常见的用法是块,如下所示:

代码语言:javascript
复制
[1, 2, 3, 4].map { |n| n*n }
# => [1, 4, 9, 16]

但是,如果您调用map而不传递一个块,它仍然返回一些内容。在本例中,它返回一个Enumerator,它知道原始数组,并且它是一个“映射”类型的数组。它可以用于链接其他Enumerator方法,例如:

代码语言:javascript
复制
[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块。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28536257

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档