map(&:name)在Ruby中是什么意思?
我在RailsCast中找到了以下代码:
def tag_names@tag_names || tags.map(&:name).join(' ')
end
什么是(&:name)
在map(&:name)
是什么意思?
#1楼
它是tags.map { |tag| tag.name }.join(' ')
的简写。 tags.map { |tag| tag.name }.join(' ')
#2楼
相当于
def tag_names@tag_names || tags.map { |tag| tag.name }.join(' ')
end
#3楼
这是tags.map(&:name.to_proc).join(' ')
的简写
如果foo
是具有to_proc
方法的对象,则可以将其作为&foo
传递给方法,该方法将调用foo.to_proc
并将其用作方法的块。
Symbol#to_proc
方法最初是由ActiveSupport添加的,但已集成到Ruby 1.8.7中。 这是它的实现:
class Symboldef to_procProc.new do |obj, *args|obj.send self, *argsendend
end
#4楼
同时让我们注意到,&符#to_proc
魔术可以与任何类一起使用,而不仅限于Symbol。 许多Ruby #to_proc
选择在Array类上定义#to_proc
:
class Arraydef to_procproc { |receiver| receiver.send *self }end
end# And then...[ 'Hello', 'Goodbye' ].map &[ :+, ' world!' ]
#=> ["Hello world!", "Goodbye world!"]
“ &
通过在其操作数上发送to_proc
消息来工作,在上面的代码中,该操作数属于Array类。 并且由于我在Array上定义了#to_proc
方法,因此该行变为:
[ 'Hello', 'Goodbye' ].map { |receiver| receiver.send( :+, ' world!' ) }
#5楼
Josh Lee的答案几乎是正确的,只是等效的Ruby代码应如下所示。
class Symboldef to_procProc.new do |receiver|receiver.send selfendend
end
不
class Symboldef to_procProc.new do |obj, *args|obj.send self, *argsendend
end
使用此代码,当执行print [[1,'a'],[2,'b'],[3,'c']].map(&:first)
,Ruby将拆分第一个输入[1,'a']
分为1,而'a'则赋予obj
1,而args*
'a'则引起错误,因为Fixnum对象1没有方法self(即:first)。
执行[[1,'a'],[2,'b'],[3,'c']].map(&:first)
;
:first
是一个Symbol对象,因此当将&:first
作为参数提供给map方法时,将调用Symbol#to_proc。map通过参数
[1,'a']
向:first.to_proc发送呼叫消息,例如,执行:first.to_proc.call([1,'a'])
。Symbol类中的to_proc过程将发送消息发送到带有参数(:first)的数组对象(
[1,'a']
),例如,执行[1,'a'].send(:first)
。迭代
[[1,'a'],[2,'b'],[3,'c']]
对象中的其余元素。
这与执行[[1,'a'],[2,'b'],[3,'c']].map(|e| e.first)
表达式相同。
#6楼
这里发生了两件事,理解这两者很重要。
如其他答案中所述,正在调用Symbol#to_proc
方法。
但是之所以在符号上调用to_proc
的原因是因为它被作为块参数传递给map
。 将&
放在方法调用中的参数前面会导致这种方式传递。 这适用于任何Ruby方法,而不仅仅是带有符号的map
。
def some_method(*args, &block)puts "args: #{args.inspect}"puts "block: #{block.inspect}"
endsome_method(:whatever)
# args: [:whatever]
# block: nilsome_method(&:whatever)
# args: []
# block: #<Proc:0x007fd23d010da8>some_method(&"whatever")
# TypeError: wrong argument type String (expected Proc)
# (String doesn't respond to #to_proc)
Symbol
被转换为Proc
因为它已作为块传递。 我们可以尝试通过将proc传递给.map
而不使用&符的方式来证明这一点:
arr = %w(apple banana)
reverse_upcase = proc { |i| i.reverse.upcase }
reverse_upcase.is_a?(Proc)
=> truearr.map(reverse_upcase)
# ArgumentError: wrong number of arguments (1 for 0)
# (map expects 0 positional arguments and one block argument)arr.map(&reverse_upcase)
=> ["ELPPA", "ANANAB"]
即使不需要转换,该方法也不知道如何使用它,因为它需要一个块参数。 用&
传递给.map
它期望的块。
#7楼
如下:
def tag_namesif @tag_names@tag_nameselsetags.map{ |t| t.name }.join(' ')
end
#8楼
在这里:name
是指向标记对象的方法name
的符号。 当我们将&:name
传递给map
,它将把name
视为proc对象。 简而言之, tags.map(&:name)
作用是:
tags.map do |tag|tag.name
end
#9楼
(&:name)是(&:name.to_proc)的缩写,它与tags.map{ |t| t.name }.join(' ')
tags.map{ |t| t.name }.join(' ')
to_proc实际上是用C实现的
#10楼
tags.map(&:name)
是相同的
tags.map{|tag| tag.name}
&:name
仅使用符号作为要调用的方法名称。
#11楼
它的意思是
array.each(&:to_sym.to_proc)
#12楼
尽管我们已经有了不错的答案,但是从初学者的角度来看,我想添加其他信息:
map(&:name)在Ruby中是什么意思?
这意味着,您要将另一个方法作为参数传递给map函数。 (实际上,您传递的是一个已转换为proc的符号。但这在这种情况下并不重要)。
重要的是,您有一个名为name
的method
,该方法将由map方法用作参数而不是传统的block
样式。
#13楼
map(&:name)接受一个可枚举的对象(在您的情况下为标签)并为每个元素/标签运行name方法,并从该方法输出每个返回的值。
这是
array.map { |element| element.name }
它返回元素(标签)名称的数组
#14楼
它基本上在数组中的每个标签上执行方法调用tag.name
。
这是简化的红宝石速记。
#15楼
许多人不知道的另一个很酷的速记是
array.each(&method(:foo))
这是的简写
array.each { |element| foo(element) }
通过调用method(:foo)
我们从self
中获取了一个Method
对象,该对象代表其foo
方法,并使用&
表示它具有to_proc
方法 ,该方法将其转换为Proc
。
当您想做无指向性的样式时,这非常有用。 一个示例是检查数组中是否有任何与字符串"foo"
相等的字符串。 有常规方法:
["bar", "baz", "foo"].any? { |str| str == "foo" }
还有一种无意义的方式:
["bar", "baz", "foo"].any?(&"foo".method(:==))
首选方式应该是最易读的方式。
map(&:name)在Ruby中是什么意思?相关推荐
- ruby 中 map方法
ruby 中 map方法 对数组中每个元素进行表达式操作,原始数组不会被改变,返回执行表达式结果的新数组 # 把 numbers 中每个值映射到 String 的 Array numbers = [1 ...
- 为什么在Ruby中使用`rescue Exception =gt; e`样式不好?
本文翻译自:Why is it bad style to `rescue Exception => e` in Ruby? Ryan Davis's Ruby QuickRef says (wi ...
- 在Ruby中,如何跳过.each循环中的循环,类似于‘continue‘[duplicate]
本文翻译自:In Ruby, how do I skip a loop in a .each loop, similar to 'continue' [duplicate] This question ...
- ruby中的符号_Ruby中的凡人和不朽符号
ruby中的符号 In this article, we're going to explore the following topics: 在本文中,我们将探讨以下主题: symbols are u ...
- ruby 数组自定义排序_在Ruby中对数组排序
ruby 数组自定义排序 Sorting was a preoccupation for computer scientists from early on. There were many algo ...
- 如何在Ruby中使用数组方法
介绍 (Introduction) Arrays let you represent lists of data in your programs. Once you have data in an ...
- Ruby中的设计模式
继续 上 节讲述过的Singleton . Proxy 及 Iterator各模式,本节再来考察几个别的设计模式.下面按顺序来考察 Prototype . Template Method 和 Obse ...
- Ruby中的设计模式——《松本行弘的程序世界》
< 设计模式 > 一书是用C++ 和 Smalltalk 介绍模式实例的.看了那些例子,大家都会感觉到,绝大多数的模式用 Smalltalk 实现起来非常简单.这是为什么呢? 因为Smal ...
- Ruby中爬虫的实现
2019独角兽企业重金招聘Python工程师标准>>> Ruby中实现网页抓取,一般用的是mechanize,使用非常简单. 安装 sudo gem install mechaniz ...
最新文章
- ​【安全牛学习笔记】WPS及其他工具WPS
- JDK自带线程池介绍及使用环境
- Blazor University (4)组件 — 单向绑定
- java 三元 代替 if_Java 中三元和 if else 哪个的效率比较高,有底层解释吗,谢谢了!...
- Windows编程之网络之邮件槽通讯
- Ant Design Tabs标签页隐藏的标签内元素无法获取到
- 探讨 | 深入探讨Redis管道
- 【运维技术】数据库主从同步搭建
- 20160507-hibernate入门
- 【GYM-100889 D】Dicy Numbers【数学推导求解】
- 写作技巧~100段作文排比句(81-100段),考试一定用得上,赶紧收藏!
- php做seo优化,php做seo优化能力有哪些
- Leetcode PHP题解D1:宝石与石头
- ionic3硬件检测、请求权限插件 Diagnostic 的用法
- 【微信云开发】简记操作:删除云开发环境
- windows版微信多开
- 【初赛】计算机操作系统
- 华为Android岗面经;群面+技术面+英语面+面试题详解
- 机房动力环境监控系统
- 最牛散户最新版唐亮一年获利超3亿
热门文章
- 3D图形学的线性代数的通俗解释。
- Android之linux基础教学之一 内存地址
- 算法-------三角形最小路径和(Java版本)
- Glide 源码分析与面试提问
- 转载:vs2010 问题 LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
- 第十、十一周项目四 - 教师兼干部类
- 第八周项目二-用对象数组操作长方柱类
- Android10.0系统启动之Launcher(桌面)启动流程-[Android取经之路]
- wireshark网络分析就这么简单_【读书笔记】2wireshark网络分析就这么简单——不同子网如何发送消息。...
- wsl2 图形界面_WSL2配置xrdp一键启动至桌面环境