2009-12-21 2 views
8

Я начал с Ruby и нашел новые, более короткие и элегантные способы писать код каждый день.Более элегантный способ сделать это в Ruby

При решении задач проекта Эйлера, я написал много кода, как

if best_score < current_score 
    best_score = current_score 
end 

есть более элегантный способ написать это?

+1

+1 для http://projecteuler.net/ – miku

+3

+1 для выполнения проектного эйлера в Ruby – akuhn

+0

Надеюсь, у'р доволен статусом статуса ура сейчас? ;) – CoffeeCode

ответ

16
best_score = [best_score, current_score].max 

см: перечислимых. max


отказ от ответственности: несмотря на то, что это немного более удобным для чтения (имхо), это менее производительным:

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 

приведет (с рубином 1.8.6 (2008-08-11 287 номера патчей)):

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

Это обманывает муху летучей мышью, нет? – guns

+2

Самое приятное в этом решении состоит в том, что массив может содержать любое количество элементов. – Geo

+1

Спасибо за тесты. Метод Max Enumerable выглядит великолепно, но мне, возможно, придется переключиться на условные выражения в конце, когда я пересекаюсь как проблема 50 :) – Anurag

15

Это может быть сделано на одной строке:

best_score = current_score if best_score < current_score 
+1

Ввод условных выражений в конце заявления просто блестящий. – Anurag

6

Может быть однострочника?

best_score = current_score if best_score < current_score 
+0

Как голова, это то же самое, что и ответ Тревора. –

0

Не уверен, что это будет квалифицироваться как «более элегантный», но если вы не хотите, чтобы переписать, если каждый раз, когда ...

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

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

-1 Он не пытается обменять переменные. Перечитайте вопрос. – Tomas

+0

@ Tomas: 'swap' является неправильным здесь. 'max' было бы более подходящим описанием того, что функция действительно делает *. – mipadi

+0

Бог, я ненавижу, когда упускаю очевидное. Спасибо;) – phtrivier

2

Это достаточно элегантно. Он читается и прост в обслуживании.

Если вы хотите короче, вы можете пойти:

best_score = current_score if best_score < current_score 

или

best_score = current_score unless best_score >= current_score 

... но это не обязательно улучшение во всех случаях (имейте в виду читаемости).

0

Или этот путь

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

Это выглядит просто отлично, как у вас есть. Я хотел бы изменить только сравнение с тем, что написано:

Если текущий счет больше, чем лучший результат

Вы также можете создать метод и назвать это. Это больше OO для меня.

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

Это то, что ООП - это не так ли? Удерживайте состояние объекта.

best_score = get_best_score() 
+0

Если мы говорим об изяществе, лучше бы узнать, лучше ли было бы лучше, чем get_best_score. или просто оценка = best_score – marcgg

+0

Поскольку вы захватываете переменные, почему бы не пойти на лямбду вместо этого? – Geo

+1

Я больше похож на OO и меньше Func – OscarRyz

1

Так как я не могу видеть его выше, я склоняюсь к этому использованию ternary operator:

best_score = current_score > best_score ? current_score : best_score 

и есть также это гораздо менее часто встречается версия:

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

... который труднее читать, но показывает (мне) слегка неожиданный побочный эффект короткого замыкания. (См. this blog post.) .) .

+1

Это хороший пост .. не должно быть выражения? best_score = (best_score> current_score && best_score) || current_score – Anurag

+0

@Anurag - да, надо, спасибо. Неадекватные тестовые примеры! Я исправлю это. –

Смежные вопросы