разряжающий массив с лимитом - PullRequest
0 голосов
/ 17 апреля 2011

У меня есть массив объектов из 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 ]

1 голос
/ 17 апреля 2011
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.Так что поместите это в условный раздел.
0 голосов
/ 17 апреля 2011

Вот наивный рефакторинг, сохраняющий те же методы, но удаляющий явные вызовы возврата и выполняющий только определенные преобразования, если это необходимо:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...