为什么“选择”不会返回真正的价值或是什么?

时间:2014-01-30 12:23:59

标签: ruby

[1,2,5,8,3].collect{|i| i.to_s} #=> ["1", "2", "5", "8", "3"]

尽管

[1,2,5,8,3].select{|i| i.to_s} #=> [1, 2, 5, 8, 3]

根据ruby-doc select => "Returns a new array containing all elements of ary for which the given block returns a true value."

这里的真值不应该是i.to_s

3 个答案:

答案 0 :(得分:2)

在红宝石中,除nilfalse以外的任何订单均为true

所以:

[1,2,5,8,3].select{|i| i.to_s}相当于[1,2,5,8,3].select{|i| true }

将评估为:

[1,2,5,8,3].select{|i| i.to_s} #=> [1, 2, 5, 8, 3]
[1,2,5,8,3].select{|i| true } #=> [1, 2, 5, 8, 3]
正如你在问题中所说的那样

  

select => “返回一个包含ary的所有元素的新数组   给定的块返回一个真值。

因此,select会返回原始数组,因为块总是计算为true。

然而collect

Returns a new array with the results of running block once for every element in enum.

所以:

[1,2,5,8,3].collect{|i| i.to_s} #=> ["1", "2", "5", "8", "3"]
[1,2,5,8,3].collect{|i| true } #=> [true, true, true, true, true]

答案 1 :(得分:1)

因为#select只选择数组中的值,所以当block被评估为非false时,并返回新数组:

{|i| i.to_s } # => false|nil or non-false|nil

#collect通过将块应用于每个当前数组值来生成新数组:

{|i| i.to_s } # => i.to_s => "String"

答案 2 :(得分:0)

您可以将#collect视为地图操作,将#select视为过滤器,因此#select的返回值始终是初始数组的子集。