新手问题 数组 collect 问题

gu_bonjour · 2015年06月08日 · 最后由 geniousli 回复于 2015年06月10日 · 2301 次阅读

操作要求是

"Ruby is an object oriented programming language" 每个单词的首字母变成大写。输出结果为"Ruby Is An Object Oriented Programming Language"

我第一遍写的是:

str = "Ruby is an object oriented programming language"
strd = ""
str.split.collect {|a| a[0]=a[0].upcase}.each{ |item|
  strd += item + " "
}
p strd.strip

本意是希望 split 所返回数组中每个元素的第一个字符改为大写,但是其返回结果是:

"R I A O O P L"

即,每个元素直接被其首字母的大写字母完全覆盖了,没有达到预期的效果。于是我改为了下面这种写法,

str = "Ruby is an object oriented programming language"
strd = ""
str.split.collect {|a| a=a[0].upcase+a[1,a.length-1]}.each{ |item|
  strd += item + " "
}
p strd.strip

返回结果正常:

"Ruby Is An Object Oriented Programming Language"
求大神笼罩,解答一下问题的原因!!!谢谢!!!

collect 方法会创建一个 Array 来接受 block 中的返回值,第一种方法返回的每个单词的首字母(即 a[0])

Ref: http://ruby-doc.org/core-2.2.0/Array.html#method-i-collect

(弱渣路过

#1 楼 @wall2flower 天了噜 竟然是你回复的我

#2 楼 @gu_bonjour 不然你以为会有一个萌妹子软软的告诉你该怎么做么 (:зゝ∠)

#3 楼 @wall2flower 你应该在句末加一句Poi 2333

str = "Ruby is an object oriented programming language"
strd = ""
str.split.collect {|a| a[0]=a[0].upcase; a}.each{ |item|
  strd += item + " "
}
p strd.strip

小改就可以。collect 是以你的表达式为返回结果的,a[0] 当然就是一个字母了。

#5 楼 @chenge {|a| a[0]=a[0].upcase; a} 这一段不是很理解,求大神解释一下 XD

唔...感觉可以写得更简单一些:

str.split.map(&:capitalize).join(' ')

#6 楼 @gu_bonjour 就是说返回 a,而不是 a[0], 明白了吗?a 才是一个单词,对吧。

#7 楼 @night_7th 求指导 map 里地 &:capitalize 是什么效果 XD

#8 楼 @chenge 明白了,所以这一句的效果是先将 a 的首字母改大写后 再返回 a 对吗?

do |a|
  a[0] = a[0].upcase
  next a
end

话说我个人比较喜欢用 map 而不是 collect

12 楼 已删除

原来还可以这样写

array. map(&:capitalize) 

@gu_bonjour 等价于:

str.split.map {|s| s.capitalize}.join(' ')

rails 有 API 可以使用,String#titleize

'man from the boondocks'.titleize   # => "Man From The Boondocks"
'x-men: the last stand'.titleize    # => "X Men: The Last Stand"
'TheManWithoutAPast'.titleize       # => "The Man Without A Past"
'raiders_of_the_lost_ark'.titleize  # => "Raiders Of The Lost Ark"

# File activesupport/lib/active_support/inflector/methods.rb, line 154
def titleize(word)
  humanize(underscore(word)).gsub(/\b(?<!['’`])[a-z]/) { $&.capitalize }
end

#18 楼 @besfan 感谢 暂时还没看到 Rails 我先过完 Ruby 哈~~

str[0] = str[0].upcase 复制之后返回的 str[0],所以才有此问题吧, 有点问题想问一下题主,比须要为了节省空间吗?ruby 一行代码可以搞定的,必要要这样用 c 的方式来写吗?

#20 楼 @geniousli 恩 5 楼的答案帮助我加深理解了 collect 的内部表达式。至于代码风格是因为初学 ruby,还停留在以前的习惯上,7 楼一句代码就搞定了也让我学习了很多。

#21 楼 @gu_bonjour 恩,说话有得罪处,请多包涵,没有表情呢为嘛

需要 登录 后方可回复, 如果你还没有账号请 注册新账号