【问题标题】:How to refactor this Ruby code?如何重构这段 Ruby 代码?
【发布时间】:2012-09-10 02:34:24
【问题描述】:

我创建了以下内容,但它看起来很神秘。有没有办法以更 Ruby 风格或更易于理解的方式编写它?

此方法会删除数字下方的较低因子。所以,10.high_factors 返回[6,7,8,9,10]。 6 可以被 2 整除,所以 2 被删除。列表中没有大于 6 的倍数,因此保留。

class Fixnum
  def high_factors
    # Get the numbers that are not divisible by lower ones below self
    list = (2..self).to_a
    2.upto(self).each do |i|
      ((i+1)..self).each { |j| list.delete i if j.is_divisible_by? i }
    end

    list
  end

  def is_divisible_by? divisor
    self % divisor == 0
  end
end

Ruby 1.9.3

【问题讨论】:

  • 我不明白这个...为什么不直接返回 [self/2+1 .. self]

标签: ruby coding-style refactoring readability


【解决方案1】:

您的方法的结果将始终是从(N/2) + 1N 的数字列表。

对于每个i<=(N/2)2*i 也会在列表中。

对于列表中的每个j >= (N/2)+1,它上面不会有一个k=x*j,其中x 是大于1 的整数,因为2*j > N

因此,如果您的方法只返回 ((self/2 + 1)..self).to_a,它也可以按您的意愿工作。

【讨论】:

  • 虽然这并没有重构任何 Ruby 代码,但它确实是最好的答案,因为它使用数学来证明正确性。
【解决方案2】:

这个呢?只删除能被大数整除的数字。

class Fixnum
  def high_factors
    # Get the numbers that are not divisible by lower ones below self
    (2..self).reject do |i|
      (i+1..self).any? { |j| j.divisible_by?(i) }
    end
  end

  def divisible_by?(divisor)
    self % divisor == 0
  end
end

ps:在 ruby​​ 中,通常省略布尔函数开头的“is_”,因为我们可以添加?

【讨论】:

    【解决方案3】:

    这是我的

    def high_factors
      ary = (2..self).to_a
      ary.reject do |factor|
        ary.index {|num| num != factor and num % factor == 0}
      end
    end
    

    如果找不到合适的匹配项,它的工作原理是 Array#index 返回 nil。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多