Day14 - Ruby比一比:#each #map和#collect method

今天要讲的是迭代器(iterator)。什么是迭代器呢?它的好处就是会一个一个地传回集合里的元素,让我们可以利用迭代方法做重复的事。

 

在Ruby里的collection集合里有Array数组和Hash哈希。

 

今天要介绍三种用在collection集合的迭代器分别叫each,map和collect,这也是常见的Ruby面试考题呢!

 

Ruby经典面试题目#14

Day14 each,map和collect比较?What's the difference between each,map and collect?

 

我们来使用这三种迭代器,在Array和Hash两种集合中各举几个生活化的例子,相信大家就比较容易暸解啰!

 

Array

Array#each

最近我在进行旅行存钱计划。我有三个银行帐户,NAB,CAN,和WESTPAC,开户金额分别为100,200,300。所以我写一个数组集合放入初始金额[100,200,300]。

 

假设我打算开始从本周开始在每个帐户存入50元(+50),可以在数组后加上.each方法:

 

[100,200,300].each {|n| puts n+50}

结果列出各个帐户的金额(注意:puts写在block大括号里):

 

150

250

350

经过.each方法作用之后,只会分别印出同一数组中各个元素的值,不会产生新数组。

 

Array#collect

以上案例,换成.collect试试看:(注意!puts写在前面)

 

puts [100,200,300].collect {|n| n+50}

.collect会帮我们把结果放入新的数组。结果印出(xujiaqing):

 

[150,250,350]

Array#map

同样的,.map方法也会帮我们产生新的数组。

 

puts [100,200,300].map {|n| n+50}

结果印出:

 

[150,250,350]

那.collect与.map又有什么不同?以及分别用在什么情况呢?这时候就要翻查Ruby手册里,关于.collect和.map的介绍了:

 

collect { |item| block }→new_ary Invokes the given block once for each element of self.Creates a new array containing the values returned by the block.

 

hmm…好像看不出有什么差异呢!

 

map { |obj| block }→array Returns a new array with the results of running block once for every element in enum.

 

近一步查询stackoverflow,果然有其他网友问过类似的问题。我们可以把.map当作是.collect的别名(map is an alias for collect),实务上比较常使用.map喔!

 

更多Array#map用法

现在把我的银行帐户数组存进account变数里,再用.inspect检查数组的值:

 

account = [100,200,300]

account.map {|n| n+50}

p account.inspect

结果印出

 

“[100,200,300]”

如果在.map后加上惊叹号.map!呢?

 

account.map!{|n| n+50}

p account.inspect

存进去原本的数组了。钱钱变多了!开心~~(加上!惊叹号的方法,通常代表小心!注意!的意思)

 

在这里的.map方法会让原本的物件数组被改变呢!

 

“[150,250,350]”

Hash

Hash哈希是一对key与value的集合。在刚刚的银行帐户例子里,我们可以把银行名称当作索引,存款数目当作值:

 

account = {“NAB”=> 100,“CAN”=> 200,“WEST”=> 300}

利用哈希来展现目前的信息(帐户名称、存款金额),这样就可读性更加清楚了。

 

Hash#each

现在我想要计算三个帐户加总共有多少钱,以.each的方式可写为:

 

mymoney = 0

account.each {|bankname,saving| mymoney += saving} #把索引和值列出

print“My Money: $”+ mymoney.to_s

或是

 

mymoney = 0 #设定初始值

account.each{|bank| mymoney += bank[1]} #依序加总bank集合里第二个元素bank[1]

print“My Money: $”+ mymoney.to_s

结果都会印出:

 

My Money: $ 600

Hash#map

在Hash里,把.each换成.map或是.collect:

 

mymoney = 0 #设定初始值

account.collect{|bank| mymoney += bank[1]} #依序加总bank集合里第二个元素bank[1]

print“My Money: $”+ mymoney.to_s

结果都是一样的:

 

My Money: $ 600

Hash#map结合Array#each与Array#map

现在要进阶到一个较为复杂的例子:hash里包含索引和值两部份,那我们可不可以把数组当作一种值,放在里面呢?

 

当然可以!

 

假设我的NAB银行下有2个子帐户,CAN银行下有3个子帐户,分别放入这些资产:

 

hash = {“NAB”=> [“Cash”,“Gold”],“CAN”=> [“Bitcoin”,“Litecoin”,“Ethereum”] }

利用hash.map会产生一个新的数组:(进一步了解说明,看stackoverflow的说明)

 

p hash.map {|n| n}

结果显示:

 

[[“NAB”,[“Cash”,“Gold”]],[“CAN”,[“Bitcoin”,“Litecoin”,“Ethereum”]]] #我有好多帐户!NAB下有2个,CAN下有3个

我想分别提取出银行:帐户名称的这一对信息,并且用逗号.join(“,”)隔开。

 

为了程序可读性,hash的索引命名为bank(银行名),值为account_arry(放了不同数目的子帐户数组)。在走account_arry.each展开数组迭代器时,每在集合里走完一个元素,就印出#{bank}:#{sub_account}

 

p hash.map {

|bank,account_arry| account_arry.each{

|sub_account|“#{bank}:#{sub_account}”}

}.join(“,”)

结果仅印出:

 

“Cash,Gold,Bitcoin,Litecoin,Ethereum”

奇怪,这不是我要的结果呀!我很希望帐户前面能显示出银行名称呢!

 

这是因为刚刚说过,arry.each会回传数组本身,在这个例子里,分别回传的是[“Cash”,“Gold”]和[“Bitcoin”,“Litecoin”,“Ethereum”]

 

改成.map试试看:

 

p hash.map {

|bank,account_arry| account_arry.map{

|sub_account|“#{bank}:#{sub_account}”}

}.join(“,”)

结果显示为:

 

“NAB: Cash,NAB: Gold,CAN: Bitcoin,CAN: Litecoin,CAN: Ethereum”

这是因为account_arry.map自动帮我们产生新的数组,放进bank与对应的sub_account并回传。

 

最后放个小小的比一比表格作为总结(expatvision):

 

each map / collect

Array方法Enumerable(列举)方法

回传Array本身产生新的Array并回传

祝福大家能顺利collect不同的资产,不管是有形的财富、还是无形的知识,最后都可以达成钱多多的心愿喔!:D

转载于:https://www.cnblogs.com/lannyQ-Q/p/11561470.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在编译过程中,当出现"找不到 -lmysqlclient collect2: error: ld returned 1 exit status"这样的错误时,意味着编译器无法找到名为"libmysqlclient"的库文件。这通常是由于库文件未正确安装或未在编译选项中正确指定所致。要解决这个问题,可以采取以下方法: 1. 确保库文件已正确安装:首先,确保系统上已正确安装了libmysqlclient库。可以使用包管理器来安装该库,例如在Ubuntu上可以使用apt-get命令进行安装。 2. 确认库文件路径:确认库文件的路径是否正确。编译器需要知道库文件所在的位置才能正确链接。可以通过在编译选项中添加正确的库文件路径来解决此问题。 3. 检查库文件名:检查库文件名是否正确。有时库文件的名称可能会略有不同,需要确保在编译选项中使用的库文件名与实际库文件的名称一致。 4. 使用软链接:如果库文件路径正确,但编译器仍然找不到库文件,可以尝试创建一个软链接。软链接是指在指定位置创建一个指向实际库文件的链接文件。可以使用ln命令来创建软链接。 综上所述,要解决"找不到 -lmysqlclient collect2: error: ld returned 1 exit status"错误,可以通过确认库文件的正确安装、路径和名称,以及使用软链接来解决这个问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [/usr/bin/ld: 找不到 -lcuda collect2: error: ld returned 1 exit status Makefile:84: recipe for target...](https://blog.csdn.net/gezongbo/article/details/121060611)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [ubuntu 解决“/usr/bin/ld:找不到 -lxml2”方法](https://blog.csdn.net/ZXF_1991/article/details/106020885)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值