2009-12-21 9 views
8

Empecé con Ruby y estoy buscando formas nuevas, más cortas y elegantes de escribir código todos los días.Manera más elegante de hacer esto en Ruby

En la resolución de problemas Proyecto Euler, he escrito un montón de código como

if best_score < current_score 
    best_score = current_score 
end 

¿Hay una manera más elegante de escribir esto?

+1

+1 para http://projecteuler.net/ – miku

+3

+1 para hacer el proyecto euler en Ruby – akuhn

+0

Esperamos que esté contento con su estado de voto ahora? ;) – CoffeeCode

Respuesta

16
best_score = [best_score, current_score].max 

véase: Enumerable. max


exención de responsabilidad: A pesar de que esto es un poco más fácil de leer (en mi humilde opinión), es menos eficiente:

require 'benchmark' 

best_score, current_score, n = 1000, 2000, 100_000 

Benchmark.bm do |x| 
    x.report { n.times do best_score = [best_score, current_score].max end } 
    x.report { n.times do 
    best_score = current_score if best_score < current_score 
    end } 
end 

dará como resultado (con Ruby 1.8.6 (2008-08-11 Patchlevel 287)):

user  system  total  real 
0.160000 0.000000 0.160000 ( 0.160333) 
0.030000 0.000000 0.030000 ( 0.030578) 
+4

Esto es golpear una mosca con un bate, ¿no? – guns

+2

Lo bueno de esta solución es que la matriz puede contener cualquier cantidad de elementos. – Geo

+1

Gracias por los puntos de referencia. El método máximo de Enumerable se ve genial, pero podría tener que cambiar a los condicionales al final cuando cruce como problema 50 :) – Anurag

15

Esto se puede hacer en una sola línea:

best_score = current_score if best_score < current_score 
+1

Poner los condicionales al final de la declaración es simplemente brillante. – Anurag

6

Tal vez una sola línea?

best_score = current_score if best_score < current_score 
+0

Como advertencia, esto es lo mismo que la respuesta de Trevor. –

0
No

seguro de que sería calificar como "más elegante", pero si usted no quiere volver a escribir el si cada vez ...

def max(b,c) 
if (b < c) 
    c 
else 
    b 
end 
end 

best = 10 
current = 20 
best = max(best,current) 
+1

-1 No está tratando de intercambiar las variables. Vuelve a leer la pregunta. – Tomas

+0

@Tomas: 'swap' es un nombre inapropiado aquí. 'max' sería una descripción más adecuada de lo que la función realmente * hace *. – mipadi

+0

Dios odio cuando echo de menos lo obvio. Gracias;) – phtrivier

2

Esto es bastante elegante. Es legible y fácil de mantener.

Si desea más corto, puede ir:

best_score = current_score if best_score < current_score 

o

best_score = current_score unless best_score >= current_score 

... pero no es necesariamente una mejora en todos los casos (hay que tener en cuenta la legibilidad).

0

O esta manera

(current_score > best_score) ? best_score = current_score : best_score 
0

se ve muy bien la forma en que ya lo tienes. Sólo cambiaría la comparación para que se lea:

Si la puntuación actual es mayor que la puntuación mejor

También puede crear un método y llama a eso. Eso es más OO para mí.

def get_best_score() 
     current_score > best_score ? 
      current_score : 
      best_score 
end 

Esto es de lo que se trata OOP is not? Mantenga el estado del objeto.

best_score = get_best_score() 
+0

Si hablamos de elegancia, best_score = get_best_score sería mejor. o simplemente puntaje = best_score – marcgg

+0

Dado que está capturando variables, ¿por qué no elegir una lambda? – Geo

+1

Soy más como OO y menos Func – OscarRyz

1

Ya que no puedo verlo más arriba, que se inclinan por este uso de la ternary operator:

best_score = current_score > best_score ? current_score : best_score 

y también hay esta versión bastante menos frecuentemente encontrado-:

best_score = (best_score > current_score && best_score) || current_score 

... que es más difícil de leer, pero muestra un (para mí) efecto secundario ligeramente inesperado de cortocircuito. (Consulte this blog post.)

+1

que es una buena publicación ... ¿no debería ser la expresión? best_score = (best_score> current_score && best_score) || current_score – Anurag

+0

@Anurag - sí, debería, gracias. ¡Casos de prueba inadecuados! Lo arreglaré. –

Cuestiones relacionadas