【问题标题】:Ruby - modifying classesRuby - 修改类
【发布时间】:2013-07-11 09:14:36
【问题描述】:

我写了一个简单的方法来检查一个数字是否是Armstrong number。 但是现在我想修改默认的 Number 类放置方法。 所以,我有代码:

def is_an(number)
    (number.to_s.split(//).map(&:to_i).inject{|x,y|x+y**(number.size-1)}) == number ? true : false
end
p is_an(153)

我想用它作为方法:153.is_a? 那么,我该怎么做呢?

class Number
   def is_an
      ??? How to use object data over here? ???
   end
end

非常感谢阅读。

【问题讨论】:

  • self替换公式中的number
  • 或者干脆直接去掉变量名,虽然有时可读性较差
  • 我试过了,但是不行。我发现了问题:我必须使用 Fixnum 类,而不是 Number。谢谢。

标签: ruby algorithm class methods


【解决方案1】:

结合@mikej 的答案,并将number 替换为self

class Fixnum
  def is_an
    digits = self.to_s.split(//).map(&:to_i)
    digits.inject(0) { |x,y| x+y**digits.size } == self
  end
end

但我建议更改名称,使其更像 Ruby。而不是#is_an,这不是很具描述性,#armstrong?怎么样,然后你可以打电话:

153.armstrong?

【讨论】:

    【解决方案2】:

    不是您原始问题的答案,但您的代码中有几个小错误。您需要将 0 传递给 inject 以用作初始值。否则,inject 将列表中的第一个值作为初始值。您当前的代码似乎适用于 153,因为 1^3 == 1 但它会为 370 返回 false,例如,当它应该返回 true 时。

    另外,size method on Fixnums 不返回数字中的位数。

    最后一点:不需要? true : false,因为... == number 表达式的值已经是所需的布尔值。所以一个可能的更新方法是:

    def is_an(number)
        digits = number.to_s.split(//).map(&:to_i)
        digits.inject(0) { |x,y| x+y**digits.size } == number
    end
    

    【讨论】:

      猜你喜欢
      • 2011-05-02
      • 2012-10-01
      • 2011-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-29
      相关资源
      最近更新 更多