2009-12-21 14 views
8

Ho iniziato con Ruby e sto trovando nuovi, più brevi ed eleganti modi di scrivere codice ogni giorno.Un modo più elegante per farlo in Ruby

nel risolvere i problemi Project Euler, ho scritto un sacco di codice come

if best_score < current_score 
    best_score = current_score 
end 

C'è un modo più elegante di scrivere questo?

+1

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

+3

+1 per fare progetto euler in Ruby – akuhn

+0

spero che tu sia felice con lo stato di votazione ur ora? ;) – CoffeeCode

risposta

16
best_score = [best_score, current_score].max 

vedere: Enumerable. max


disclaimer: anche se questo è un po 'più leggibile (imho), è meno performante:

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 

si tradurrà in (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

Questo sta schiacciando una mosca con una mazza, no? – guns

+2

La cosa bella di questa soluzione è che l'array può contenere un numero qualsiasi di elementi. – Geo

+1

Grazie per i parametri di riferimento. Il metodo max di Enumerable sembra ottimo, ma potrei dover passare ai condizionali alla fine quando incrocio il problema 50 :) – Anurag

15

Questo può essere fatto su una sola riga:

best_score = current_score if best_score < current_score 
+1

Mettere i condizionali alla fine della dichiarazione è semplicemente geniale. – Anurag

6

Forse una battuta?

best_score = current_score if best_score < current_score 
+0

A testa alta, è la stessa risposta di Trevor. –

0
Non

sicuro che sarebbe qualificarsi come "più elegante", ma se non si vuole riscrivere la se ogni volta ...

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

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

-1 Non sta cercando di scambiare le variabili. Rileggi la domanda – Tomas

+0

@Tomas: 'swap' è un termine improprio qui. 'max' sarebbe una descrizione più appropriata di ciò che la funzione * effettivamente * fa *. – mipadi

+0

Dio odio quando mi manca l'ovvio. Grazie;) – phtrivier

2

Questo è abbastanza elegante. È leggibile e facile da mantenere.

Se volete più breve, si può andare:

best_score = current_score if best_score < current_score 

o

best_score = current_score unless best_score >= current_score 

... ma non è necessariamente un miglioramento in tutti i casi (tenere a mente la leggibilità).

0

O questo modo

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

Sembra proprio il modo in cui ce l'hai già. Cambierei solo il confronto in modo che legge:

Se il punteggio attuale è maggiore miglior punteggio

È anche possibile creare un metodo e chiami. Questo è più OO per me.

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

Questo è ciò di cui si occupa OOP no? Tieni lo stato dell'oggetto.

best_score = get_best_score() 
+0

Se parliamo di eleganza, best_score = get_best_score sarebbe meglio. o semplicemente punteggio = best_score – marcgg

+0

Dato che stai catturando le variabili, perché non optare per una lambda? – Geo

+1

Sono più simile a OO e meno Func – OscarRyz

1

Dal momento che non riesco a vedere al di sopra, mi appoggio verso questo uso del ternary operator:

best_score = current_score > best_score ? current_score : best_score 

e c'è anche questa versione un po 'meno frequentemente incontrati:

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

... che è più difficile da leggere, ma mostra un (a me) effetto collaterale leggermente inaspettato di corto circuito. (Vedi this blog post.)

+1

questo è un bel post .. non dovrebbe essere l'espressione? best_score = (best_score> current_score && best_score) || current_score – Anurag

+0

@Anurag - sì, dovrebbe, grazie. Casi di test inadeguati! Lo aggiusterò. –

Problemi correlati