Я хотел бы предложить другое решение:
def dashes(num)
str = num.to_s
dashed_arr = str.chars.map.with_index do |digit, index|
next digit if digit.to_i.even?
if index.zero? # is it first digit?
"#{digit} -"
elsif index == str.length - 1 # is it last digit?
"- #{digit}"
else
"- #{digit} -"
end
end
dashed_arr.join(' ').gsub('- -', '-')
end
puts dashes(95601137)
puts dashes(909)
# => "9 - 5 - 6 0 - 1 - 1 - 3 - 7"
# => "9 - 0 - 9"
Давайте рассмотрим его шаг за шагом:
str = num.to_s
- преобразовать наше число в строковое представление, т.е. "95601137"
str.chars
- разделите нашу строку символами. Мы получаем массив символов, например: ["9", "5", "6", "0", "1", "1", "3", "7"]
, потому что мы хотим их повторить, один за другим.
map
принимает один массив и преобразует его в другой массив по коду, указанному в do ... end
.
Например, давайте рассмотрим этот код:
[1, 2, 3].map do |num|
num * 2
end
# => [2, 4, 6]
Если вам нужно также индекс вашего элемента, вы можете так же использовать .map.with_index
(индекс начинается с нуля):
[1, 2, 3].map.with_index do |num, index|
num * index # index takes values 0, 1, 2
end
# => [0, 2, 6]
Итак, в блоке в коде выше, у нас есть каждая цифра из нашего номера как digit
и ее 0-позиция в виде index
.
next digit if digit.to_i.even?
. Нам не нужны даже цифры, поэтому мы можем пропустить их. .to_i
необходим для преобразования digit
в integer, поэтому мы можем запросить его четное или нечетное. next digit
просто возвращает текущую цифру и перемещает выполнение до следующей цифры.
Теперь мы остаемся только с нечетными цифрами, поэтому нам нужно просто поместить тире правильно, в зависимости от позиции цифр: если это первая цифра, добавьте тире, если это последняя цифра, тогда введите тире в передняя часть цифр, в противном случае просто окружать цифры с тиром:
if index.zero? # first digit, index is zero-based
"#{digit} -"
elsif index == str.length - 1 # last digit
"- #{digit}"
else
"- #{digit} -"
end
Мы экономим промежуточный результат в dashed_arr
переменном, чтобы сделать код читаемым. Сейчас он содержит следующее: ["9 -", "- 5 -", "6", "0", "- 1 -", "- 1 -", "- 3 -", "- 7"]
. Как вы можете видеть, мы почти закончили, нам просто нужно связать все элементы массива с строкой.
dashed_arr.join(' ')
. Объединение элементов массива в строку с одиночным пространством в качестве разделителя. Мы получаем эту строку: 9 - - 5 - 6 0 - 1 - - 1 - - 3 - - 7
. Хм, кажется, нам нужно удалить несколько последовательных тире.
Давайте сделаем это с gsub
: dashed_arr.join(' ').gsub('- -', '-')
. gsub
просто ищет все вхождения первой строки и заменяет их второй строкой, которая именно то, что нам нужно: 9 - 5 - 6 0 - 1 - 1 - 3 - 7
.
Все готово! Надеюсь, это было так же весело для вас, как и для меня.
Я очень благодарен за все ваши ребята! –