我有一个if / else条件,if和else部分是相同的,除了使用的运算符。在一个案例中<
,在另一个案例>
中。有没有办法有条件地设置该运算符,以干掉代码?
if count_year < end_year
while count_year <= end_year
if count_year % 4 == 0
if count_year % 100 != 0
all_years << count_year unless (count_year % 400 == 0)
end
end
count_year += 1
end
puts all_years
elsif count_year > end_year
while count_year >= end_year
if count_year % 4 == 0
if count_year % 100 != 0
all_years << count_year unless (count_year % 400 == 0)
end
end
count_year -= 1
end
puts all_years.reverse
end
这是在两年之间打印闰年的计划的一部分。我觉得必须有一种方法可以不必重复循环两次。类似于:count_year < end_year ? operator = "<" : operator = ">"
- 然后使用该变量将运算符替换为代码块或其他内容?有什么想法吗?
答案 0 :(得分:3)
对于一个小改进,您可以将完全相同的部分提取到方法中。然后重复停止如此庞大。
# I'm too lazy to come up with a proper name for it.
def foo count_year, all_years
if count_year % 4 == 0
if count_year % 100 != 0
all_years << count_year unless (count_year % 400 == 0)
end
end
end
# later...
if count_year < end_year
while count_year <= end_year
foo count_year, all_years
count_year += 1
end
puts all_years
elsif count_year > end_year
while count_year >= end_year
foo count_year, all_years
count_year -= 1
end
puts all_years.reverse
end
是的,有一种方法可以动态选择运营商进行评估。你看,ruby中的运算符只是方法调用,仅此而已。这两行是等价的:
7 > 5
7.>(5)
这是一个选择随机运算符进行比较的片段。我把它留给你来适应你的问题(如果你愿意,那就是。我建议你不要这样做。)
def is_7_greater_than_5
operator = [:<, :>].sample # pick random operator
7.send(operator, 5)
end
is_7_greater_than_5 # => false
is_7_greater_than_5 # => false
is_7_greater_than_5 # => true
is_7_greater_than_5 # => true
is_7_greater_than_5 # => true
答案 1 :(得分:2)
def example count_year, end_year
all_years = []
dir, test = count_year < end_year ?
[ 1, proc { |c, e| c <= e }] : count_year > end_year ?
[-1, proc { |c, e| c > e }] :
[ 0, proc { |c, e| false }]
while test.call count_year, end_year
if count_year % 4 == 0
if count_year % 100 != 0
all_years << count_year unless count_year % 400 == 0
end
end
count_year += dir
puts dir > 0 ? all_years : all_years.reverse
end
end
答案 2 :(得分:0)
噢。你为什么要进行高尔夫练习并快速接受答案?嘘! :(嘿嘿。开个玩笑。早起的小鸟得了蠕虫。我也许太过字面意思了,因为我觉得你只是想试试比较。
我会使用ruby的内置函数并将此方法分解为一个类。 :)
require 'date'
class LeapYearFinder
attr_reader :years, :years_reversed
def initialize(start_year, end_year)
@start_year = Date.parse("1/1/#{start_year.to_s}")
@end_year = Date.parse("1/1/#{end_year.to_s}")
@years ||= leap_years
end
def compare_range
@compare_range ||= Range.new(@start_year, @end_year)
end
def leap_years
years = []
compare_range.step {|x| years << x.year if x.leap? }
years.uniq!
end
def years_reversed
@years.reverse
end
end
lp = LeapYearFinder.new(1900, 2012)
puts "Years putzed"
lp.years.map {|x| puts x}
puts "Years reversed"
lp.years_reversed.map {|x| puts x}