2015-05-03 3 views
0

Я проходил упражнения в Ruby Monk, и у меня возникли проблемы с расшифровкой одного из примеров решений.Ruby - расшифровка:

Проблемы (from this page) была:

Написать метод, который подсчитывает количество элементов массива, который передаются в, только если индекс числа 42 в одномерного представление массива 5.

Мое решение, которое работало нормально, было:

def zen(array) 
    converted_array = array.flatten.compact 
    converted_array.count if converted_array.index(42) == 5 
end 

Их решение было:

def zen(array) 
    converted = array.compact.flatten 
    converted.index(42) == 5 ? converted.count : nil 
end 

Я понимаю Everthing слева от : во второй строке метода, но после этого я не могу понять это. Я думал, что compact удаляет все значения nil из массива?

+0

':' идет с '?', Это единственный оператор. Это ярлык: 'a? B: c' is' if (a) then b else c'. – Mat

+0

http://stackoverflow.com/questions/4252936/how-do-i-use-the-conditional-operator-in-ruby – Mat

+0

@Mat, большое спасибо за разъяснение этого. Если вы ответите, я с удовольствием приму это. – SoSimple

ответ

3

?...: известен как оператор Ternary. Предположим, что мы хотели установить переменную x равной AM или PM на основе текущего времени. На простом языке мы могли бы сказать:

x='AM' if time < '12:00' but x='PM' if time > '12:00' 

Очевидно, однако, что это не действует рубин Мы можем сделать то же самое с тройным оператором, упрощая то, что бы в противном случае стать два условными (или что-нибудь еще в этом отношении!):

x = time < '12:00' ? 'AM' : 'PM' 

Зная, что так оно и работает, мы можем теперь понять последнюю строку вашей функции zen. Понимая это последняя строка очень важна ...

converted.index(42) == 5 ? converted.count : nil 

Вы правы, что компактный удалим Nils, но это не смотрит, чтобы увидеть, если есть Нильс внутри результирующего массива. Вместо этого это проверяет, есть ли элемент 42 в этом массиве 5. Если это так, вся функция возвращает converted.count. Если он не равен 5, вся функция возвращает nil.

Почему? Поскольку полученное значение последней строки функции в Ruby возвращается как возвращаемое значение. Если вы думаете об этом, это справедливо и для заявления return, так как оно оценивает все, что вы делаете справа!

+0

Большое спасибо за это. Это очень полезно! – SoSimple

+0

Ваш пример в точности эквивалентен 'x = если время <'12: 00 ', затем' AM 'else' PM 'end'. В общем, в отличие от других языков, где 'if' является оператором, а условный оператор является выражением, редко требуется использовать условный оператор в Ruby, поскольку' if' также является выражением (на самом деле, нет заявления в Ruby). Действительно, единственная разница - это краткость (что не всегда хорошо) и приоритет, а приоритет условного оператора сработал довольно много программистов, о чем свидетельствуют вопросы об этом здесь, на SO. –

+0

Примечание: это не критика вашего ответа. –