que sugeriría la construcción de un hash indexado por mes como Entonces:
@quarters_by_month = Hash[(1..12).map {|v| i=((v-1)/3)*3; [v,[i+1, i+2, i+3]]}]
entonces cualquier consulta de futuro es sólo
@quarters_by_month[month]
Desde @ x3ro tiempo de CPU mencionada pensé que sería divertido referencia todas las soluciones propuestas, incluyendo la declaración case
el que el PO quiere excluir. Aquí están los resultados:
> ruby jeebus.rb
user system total real
case_statement: 0.470000 0.000000 0.470000 ( 0.469372)
quarter_month: 0.420000 0.000000 0.420000 ( 0.420217)
solution1: 0.740000 0.000000 0.740000 ( 0.733669)
solution2: 1.630000 0.010000 1.640000 ( 1.634004)
defined_hash: 0.470000 0.000000 0.470000 ( 0.469814)
Aquí está el código:
def case_statement(month)
case month
when 1,2,3
[1,2,3]
when 4,5,6
[4,5,6]
when 7,8,9
[7,8,9]
when 10,11,12
[10,11,12]
else
raise ArgumentError
end
end
def defined_hash(month)
@quarters_by_month[month]
end
def solution1(month)
(((month - 1)/3) * 3).instance_eval{|i| [i+1, i+2, i+3]}
end
def solution2(month)
[*1..12][((month - 1)/3) * 3, 3]
end
def quarter_month_numbers(month)
@quarters[(month - 1)/3]
end
require 'benchmark'
n = 1e6
Benchmark.bm(15) do |x|
x.report('case_statement:') do
for i in 1..n do
case_statement(rand(11) + 1)
end
end
x.report('quarter_month:') do
@quarters = [[1,2,3], [4,5,6], [7,8,9], [10,11,12]]
for i in 1..n do
quarter_month_numbers(rand(11) + 1)
end
end
x.report('solution1:') do
for i in 1..n do
solution1(rand(11) + 1)
end
end
x.report('solution2:') do
for i in 1..n do
solution2(rand(11) + 1)
end
end
x.report('defined_hash:') do
@quarters_by_month = Hash[(1..12).map {|v| i=((v-1)/3)*3; [v,[i+1, i+2, i+3]]}]
for i in 1..n do
defined_hash(rand(11) + 1)
end
end
end
¿Por qué estás en contra del uso de una declaración de caso aquí? Sería una manera muy simple de hacer lo que estás preguntando. –
Estoy de acuerdo con Andy Waite, realmente DEBERÍA usar una declaración de cambio para tal problema. Todo lo demás sería solo un desperdicio de tiempo de CPU. – fresskoma