Ruby!map不改变对象类型

时间:2013-04-09 16:03:15

标签: ruby

我一直在研究一些项目欧拉问题,以帮助学习编程,并想知道是否有人可以向我解释这一点。

我有一串数字,我正在尝试找到序列中任意五个的最大产品。这就是我到目前为止所做的:

temp = series.split(//).map!{|x| x.to_i}
len = temp.length
maxprod = 1
0.upto(len-4) do |x|
    num = (temp[x] * temp[x+1] * temp[x +2] * temp[x+3] * temp[x+4])

    if num > maxprod
        maxprod = num
    end

end 

puts maxprod

temp [0] .class返回一个fixnum但是,当我运行代码时出现错误“*:nil无法强制进入FixNum(TypeError)”

由于

1 个答案:

答案 0 :(得分:4)

这是因为map返回一个数组。 map!返回nil。然后,您接受nil map!返回并将其放入temp

它们都仍在split结果的每个元素上运行块,但是当您希望将结果放入变量时,应始终使用map。这是一个微妙的事情,可以轻松地绊倒你。

更改

temp = series.split(//).map!{|x| x.to_i}

temp = series.split(//).map{|x| x.to_i}

<强>加成:

您可以使用&符号&和方法名称作为符号将块传递到map

temp = series.split(//).map(&:to_i)

修改

根据您的评论,在乘以数组元素时仍然会出现错误。这可能是因为您的temp数组没有您认为的那么多元素。尝试使用索引访问数组时,它当前没有任何内容会导致nil

temp = [1]
temp[0] #=> 1
temp[1] #=> nil
temp[0] * temp[1] #=> TypeError: nil can't be coerced into FixNum 

您提到使用temp[1].to_i修复此问题。这是因为nil可以转换为整数。

nil.to_i #=> 0

我会检查temp的结果,以确保它包含您认为包含的内容。 您可能还想查看Enumerable#each_slice,它接受​​一个数组的子集并在一个块中处理它。

nums = %w{08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08}.map(&:to_i)
nums.each_slice(4) {|a| puts a.inject(:*)}