【问题标题】:rubymonk "all elements in an array are Fixnum"?rubymonk“数组中的所有元素都是Fixnum”?
【发布时间】:2013-03-31 20:09:57
【问题描述】:

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

红宝石和尚建议:

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

这很好,但是以下代码在 irb 1.9.2 中有效,但当 ruby​​monk 传递一个空数组时失败:

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

以下是 ruby​​monk 对我的解决方案的评价:

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

【问题讨论】:

    标签: ruby


    【解决方案1】:

    你的代码有两个问题:

    1. 这个问题的措辞有点含糊。他们真正想要的是,如果任何元素不是 Fixnums,则返回 false,否则返回 true——因此空数组应该返回 true。如果您查看您的代码,您会看到result 开始时为假,因此如果数组为空,即使测试认为它应该为真,它也会返回假。你可以从 true 开始解决这个问题。

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

    【讨论】:

    • 谢谢。这更有意义。那么为什么我们给一个空数组带来怀疑的好处呢?它似乎处于量子边缘,它不是一个 Fixnums 数组,也不是一个不是 Fixnums 的东西数组?
    • @cheshirecatalyst 这是真的,你可以合理地争论真假。我真正能说的是 true 是“all”类型算法的传统默认值,可能是因为它是最明显的实现。 (相反,any? 默认为 false,大概是出于同样的原因。)
    【解决方案2】:

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

    【讨论】:

    • 非常感谢,我根据 Chuck 和您的回复更新了代码
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-31
    • 1970-01-01
    • 1970-01-01
    • 2023-02-21
    • 2014-10-25
    • 2018-06-08
    • 2015-01-08
    相关资源
    最近更新 更多