2012-05-07 2 views
2

Мне нужен метод, который вычисляет доступные недели на основе текущей даты и уже используемых дат.рассчитать свободные недели в рубине

Я придумал разные решения, но все они кажутся «уродливыми» для Ruby. Я знаю, что есть лучший способ сделать это.

Требования:

Метод принимает 3 аргумента

start - Date, to start calculation from 

amount - Integer, How many weeks do we want? 

used_weeks - Array of already used weeknumbers (optional) Default: nil 

Допустим, мы проходим метод это:

calculate_available_weeks (Date.current, 5, [1,3,7]) 

(скажем, Date.current возвращает Sun, 01 Jan 2012 для простоты)

Затем метод должен возвращать Даты в течение следующих недель: 2,4,5,6,8

Вот что у меня до сих пор:

def calculate_week_dates(start, amount, excluded_weeks = nil) 
    weeks = [] 

    last_checked = start 
    until weeks.length == amount do 
    unless excluded_weeks && excluded_weeks.include?(last_checked.cweek) 
     weeks << last_checked 
    end 
    last_checked = last_checked.next_week 
    end 

    weeks 
end 
+0

Ваш пример вывода не соответствует вашему примеру кода. Кажется, вы указываете числа cweek в выводе, но ваш код принимает исключения в исключении, но в его результате генерирует даты, а не числа недели. Что вы хотите получить, когда текущие плюс количество недель завершается в следующем году? – dbenhur

ответ

1

Вот почему я люблю рубин.

def calculate(starting_week, amount, excluded_weeks = []) 
    ((starting_week..52).to_a - excluded_weeks).first(amount) 
end 

puts calculate(1, 5, [1,3,7]).inspect # => [2, 4, 5, 6, 8] 
puts calculate(5, 5, [1,3,7]).inspect # => [5, 6, 8, 9, 10] 
puts calculate(10, 5, [1,3,7]).inspect # => [10, 11, 12, 13, 14] 
+0

Что происходит, когда start_week + amount + excluded_weeks.size завершается в следующем году? – dbenhur

+0

Это не сработает. @Tim: Требуется ли упаковка? – iblue

+0

@iblue: Да, это так, потому что я прохожу в качестве даты, отличный снимок других вычислений! –

1

Ну, вы можете сделать это сцепление функциональных счетчиков:

def calculate_week_dates(start, amount, excluded_weeks = []) 
    (0 ... amount + excluded_weeks.size). 
    inject([start]) {|a,wk| a << a.last.next_week }. 
    reject {|wk| excluded_weeks.include? wk.cweek }. 
    first(amount) 
end 

Но я смешанное чувство ли это яснее или красивее, чем петли накопления. В любом случае вам лучше утверждать, что excluded_weeks - пустой массив вместо nil, чтобы избежать более поздних nil-охранников, когда вы хотите его использовать.

Смежные вопросы