rubymonk“数组中的所有元素都是Fixnum”?

时间:2013-03-31 20:09:57

标签: ruby

http://rubymonk.com/learning/books/1/problems/148-array_of_fixnum

Ruby和尚建议:

def array_of_fixnums?(array)
  array.all? { |x| x.is_a? Fixnum }
end

这很好,但是以下代码在irb 1.9.2中有效但在rubymonk传递空数组时失败:

def array_of_fixnums?(array)
  result = false
  array.each { |n|
    if n.is_a? Fixnum
      result = true
    else
      result = false
    end }
  result
end

这里是irb输出:

1.9.2-p320 :001 > array_of_fixnums? []
 => false

以下是rubymonk关于我的解决方案的说法:

returns 'true' for [1,2,3] ✔
returns 'false' for ['a',1,:b] ✔
returns 'true' for []
    RSpec::Expectations::ExpectationNotMetError
    expected false to be true

我想知道为什么会这样?

根据答案进行更新:

def array_of_fixnums?(array)
  result = true
  array.each { |n| return false unless n.is_a? Fixnum }
  result
end

2 个答案:

答案 0 :(得分:1)

您的代码有两个问题:

  1. 问题的表达方式略显模糊。他们实际想要的是如果任何元素不是Fixnums则返回false,否则返回true - 所以空数组应该为true。如果查看代码,您会看到result开始为false,因此如果数组为空,即使测试认为它应该为真,它也会返回false。您可以通过以true开头来解决此问题。

  2. 您的代码实际上只是检测数组的 last 元素是否为Fixnum。我们来看一下数组[1, "nope", 3]。它首先会看到1并将result设置为true,然后它会看到“nope”并将result设置为false,然后它会看到3并将result设置为true,这就是该方法将返回。 RubyMonks测试实际上没有检测到这个错误,但它会出现在现实世界中。您希望在获得错误结果后立即返回,因为这足以确定阵列所有Fixnums。

答案 1 :(得分:0)

对于这种情况,您将永远不会进入每个周期,因为array中没有元素。因此,您返回在上面一行中设置为false的result的defualt值。但是,如果数组中没有元素,那么它的所有元素都是Fixnums,所以你应该返回true。