稀有阵列有限制

时间:2011-04-17 14:31:14

标签: ruby-on-rails ruby refactoring

我有AR的对象数组 我想用极限来限制它们。

当前方法如下:

  def rarefied_values(limit = 200)
    all_values = self.values.all
    rarefied_values = []

    chunk_size = (all_values.size / limit.to_f).ceil
    if all_values.size > limit
      all_values.each_slice(chunk_size) do |chunk|
        rarefied_values.push(chunk.first)
      end
      return rarefied_values
    else
      return all_values
    end
  end

重构的任何提示?

2 个答案:

答案 0 :(得分:1)

def rarefied_values(limit = 200)
  all_values = values.all
  return all_values unless all_values.size > limit
  chunk_size = all_values.size / limit
  (0...limit).map{|i| all_values[i*chunk_size]}
end

ruby​​中重构的一些要点

  • self通常可以省略。在少数情况下,您不能,例如self.class。在这种情况下,self.values.all => values.all
  • 如果其中一个条件化程序与其他程序相比要简单得多,那么首先放置该简单案例,然后使用return将其从其余代码中删除。在这种情况下,return all_values unless all_values.size > limit
  • 一般情况下,当您需要嵌套条件时,请对其进行设计,以便使用较简单的程序拆分收集器,并将复杂的情况放在最后。
  • 让代码尽可能地懒惰。在这种情况下,如果rarefied_values = [],则不需要all_values.size > limit。所以把它放在条件部分。

答案 1 :(得分:0)

这是一个天真的重构,保持相同的方法,但删除显式的返回调用,只在必要时执行某些转换:

def rarefied_values(limit = 200)
  all_values = self.values.all
  if all_values.size <= limit
    all_values
  else
    chunk_size = (all_values.size / limit.to_f).ceil
    [].tap{ |rare| all_values.each_slice(chunk_size){ |c| rare << c.first } }
  end
end

这是一个更快,更简洁的版本:

def rarefied_values(limit = 200)
  all_values = self.values.all      
  if (size = all_values.size) <= limit
    all_values
  else
    all_values.values_at(*0.step(size-1,(size.to_f/limit).ceil))
  end
end