2009-12-21 10 views
8

Ich habe mit Ruby begonnen und finde neue, kürzere, elegante Möglichkeiten, Code jeden Tag zu schreiben.Elegantere Art, dies in Ruby zu tun

Projekt Euler Probleme zu lösen, habe ich wie viel Code geschrieben

if best_score < current_score 
    best_score = current_score 
end 

Gibt es eine elegantere Möglichkeit, dies zu schreiben?

best_score = current_score if best_score < current_score 
+1

+1 für http://projecteuler.net/ – miku

+3

+1 für das Projekt Euler in Ruby – akuhn

+0

hoffen, dass wir glücklich mit Ihrem Stimmstatus jetzt sind? ;) – CoffeeCode

Antwort

16
best_score = [best_score, current_score].max 

siehe: Enumerable. max


Haftungsausschluss: Obwohl dies ein wenig besser lesbar (imho) ist, ist es weniger performant:

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 

führt in (mit 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

Das ist eine Fliege mit einer Fledermaus schlagen, nicht? – guns

+2

Das Schöne an dieser Lösung ist, dass das Array eine beliebige Anzahl von Elementen enthalten kann. – Geo

+1

Danke für die Benchmarks. Die maximale Methode von Enumerable sieht gut aus, aber ich muss eventuell zu den Bedingungen am Ende wechseln, wenn ich das Problem 50 überschreite :) – Anurag

15

Dies kann auf einer einzigen Zeile durchgeführt werden

best_score = current_score if best_score < current_score 
+1

Putting die Bedingungen am Ende der Aussage ist einfach genial. – Anurag

6

Vielleicht ein Einzeiler:

+0

Als Kopf, das ist das gleiche wie Trevors Antwort. –

0

Nicht sicher, es würde qualifizieren als „eleganter“, aber wenn Sie nicht wollen, die neu zu schreiben, wenn jedes Mal ...

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

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

-1 Er versucht nicht, die Variablen zu tauschen. Lesen Sie die Frage erneut. – Tomas

+0

@Tomas: 'swap' ist hier eine falsche Bezeichnung. 'max' wäre eine passendere Beschreibung für das, was die Funktion tatsächlich * tut *. – mipadi

+0

Gott hasse ich, wenn ich das Offensichtliche vermisse. Danke;) – phtrivier

2

Das elegante genug ist. Es ist lesbar und leicht zu pflegen.

Wenn Sie kürzer möchten, können Sie gehen:

best_score = current_score if best_score < current_score 

oder

best_score = current_score unless best_score >= current_score 

... aber es ist nicht unbedingt eine Verbesserung in allen Fällen (beachten Sie die Lesbarkeit).

0

Oder diese Weise

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

es sieht gut aus, so wie Sie es bereits haben. Ich würde nur den Vergleich ändern, so heißt es:

Wenn die aktuelle Punktzahl größer als beste

Partitur Sie können auch eine Methode erstellen und das nennen. Das ist mehr OO für mich.

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

Das ist es, worum es bei OOP geht? Halte den Objektstatus.

best_score = get_best_score() 
+0

Wenn wir über Eleganz sprechen, wäre best_score = get_best_score besser. oder nur score = best_score – marcgg

+0

Da Sie Variablen erfassen, warum nicht ein Lambda stattdessen gehen? – Geo

+1

Ich bin eher wie OO und weniger Func – OscarRyz

1

Da kann ich es nicht oben sehen, lehne ich mich gegen diese Verwendung der ternary operator:

best_score = current_score > best_score ? current_score : best_score 

und es gibt auch diese eher weniger häufig anzutreffende Version:

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

... die schwerer zu lesen ist, aber einen (mir) etwas unerwarteten Nebeneffekt des Kurzschlusses zeigt. (Siehe this blog post.)

+1

das ist ein schöner Beitrag .. sollte nicht der Ausdruck sein? best_score = (best_score> aktueller_score && best_score) || current_score – Anurag

+0

@Annorag - ja es sollte, danke. Unzureichende Testfälle! Ich werde es reparieren. –

Verwandte Themen