Хотя мы определенно могли бы улучшить это с помощью инструментов Ramda, кажется, есть очень мало причин для этого. Я думаю, что ваша цель немного ошибочна. Рамда (отказ от ответственности: я один из его авторов) разработан, чтобы предложить вам инструменты, которые помогут вам кодировать определенным образом. Это не новый диалект JS, в который вы должны конвертировать весь свой код.
Я бы написал эту функцию примерно так:
const formatHour = (time) => {
const [h, m] = time .split (':')
return `${h > 12 ? h - 12 : h}:${m} ${h >= 12 ? 'PM' : 'AM'}`
}
console .log (formatHour ('13:22'))
Основные моменты, которые я проверяю, когда хочу убедиться, что пишу функциональный код, заключаются в том, что то, что я пишу, не связано с мутацией данных (обычно это включает в себя не переназначение переменные, хотя когда-нибудь я это сделаю по соображениям производительности) и что у меня есть только чистые функции - те, которые всегда возвращают один и тот же вывод для одного и того же ввода и не имеют побочных эффектов. Эта функция проходит оба теста. Мы ничего не мутируем и присваиваем h
и m
только один раз, без переназначения. Функция полагается только на свои аргументы для вычисления непротиворечивого результата, не затрагивая ничего снаружи.
Есть некоторые другие функции, которые я предпочитаю при написании функционального кода, но они менее важны и, возможно, более противоречивы. Мне не нравится иметь много промежуточных переменных, и если они используются только один раз, я часто добавляю их в строку. Поэтому я предпочитаю версию выше этой:
const formatHour = (time) => {
const [hour, minute] = time .split (':')
const newHour = hour > 12 ? hour - 12 : hour
const meridian = hour >= 12 ? 'PM' : 'AM'
return `${newHour}:${minute} ${meridian}`
}
Но это незначительное предпочтение, и я часто выбираю другой путь, если мой код начинает чувствовать себя нечитаемым без вспомогательных локальных переменных. Другой, однако, я стараюсь делать как можно чаще: я предпочитаю работать с чистыми выражениями, а не с утверждениями. Я буду использовать условные операторы (троичные) над if
-общениями. Я выберу тела с одним выражением для функций со стрелками над {
- }
-ограниченными блоками.
Это побудило бы меня написать эту функцию следующим образом:
const formatHour = (time, [h, m] = time .split (':')) =>
`${h > 12 ? h - 12 : h}:${m} ${h >= 12 ? 'PM' : 'AM'}`;
И часто Я делаю такие вещи. Но используемые по умолчанию параметры могут быть головной болью. Используя более ранние версии функции, я мог написать
['7:04', '11:59', '12:01', '13:22'] .map (formatHour)
//=> ["7:04 AM", "11:59 AM", "12:01 PM", "1:22 PM"]
Но в этой последней версии это не сработает. Array.prototype.map
предоставляет два дополнительных параметра помимо текущего элемента: его индекс и весь массив. Так что в этой последней версии, если мы передадим его в map
, параметры [h, m]
не будут правильно сформированы, поскольку в этом месте есть целочисленный индекс, а не массив. Мы получим какую-то ошибку разрушения. Мы можем исправить это, добавив несколько неиспользуемых параметров, например:
const formatHour = (time, _, __, [h, m] = time .split (':')) =>
`${h > 12 ? h - 12 : h}:${m} ${h >= 12 ? 'PM' : 'AM'}`;
['7:04', '11:59', '12:01', '13:22'] .map (formatHour)
//=> ["7:04 AM", "11:59 AM", "12:01 PM", "1:22 PM"]
Но это кажется неуклюжим. Я делаю это иногда, особенно для внутренних функций. Но когда вы не знаете, как ваша функция будет использоваться в дикой природе, это риск.
Рамда не предлагает никаких улучшений, которые я вижу.
Но, если Я должен был попытаться сделать это с функциями Рамды, я мог бы сделать это немного иначе, чем вы.
Прежде всего, есть несколько более простых альтернатив Рамде cond
, когда вы только в одном случае ifElse
. Но даже это может быть излишним, когда одна из ваших ветвей просто возвращает данные без изменений. Затем вы можете использовать when
(или его аналог, unless
) для преобразования данных при выполнении условия и в противном случае оставить его в покое.
Во-вторых , Я бы, вероятно, использовал функцию evolve
, чтобы позволить мне изменить одну часть моей структуры данных (массив со свойствами hour
и minute
), но оставить другие части в покое.
Наконец, поскольку мне приходится использовать час в двух местах и объединять их результаты в одно, я бы использовал converge
или, что еще лучше, если это возможно, lift
, чтобы справиться с этим.
const formatHour = pipe (
split (':'),
lift (([h, m], meridian) => `${h}:${m} ${meridian}`) (
evolve ([when (gt (__, 12), subtract (__, 12))]),
([h, m]) => h >= 12 ? 'PM' : 'AM'
)
);
console .log (
['7:04', '11:59', '12:01', '13:22'] .map (formatHour)
)
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js"></script>
<script> const {pipe, split, lift, evolve, when, gt, __, subtract} = R </script>
Обратите внимание, что я не пытаюсь сделать это полностью бессмысленным. Я мог бы пойти этим путем, заменив
([h, m]) => h >= 12 ? 'PM' : 'AM'
на
ifElse(pipe(head, gte(__, 12)), always('PM'), always('AM'))
, и я уверен, что мы могли бы сделать что-то еще более ужасное для
([h, m], meridian) => `${h}:${m} ${meridian}`
Но я не надену не вижу в этом смысла. Мы уменьшаем читаемость здесь, и было бы еще хуже, если бы мы попробовали другой.
И в этом все дело. Рамда это инструмент. Используйте его, когда он улучшает что-то важное в вашем коде: удобочитаемость, удобство обслуживания, производительность или что-то еще ощутимое. Но не используйте его просто потому, что он доступен и уже включен в ваш проект. Цель никогда не должна звучать так: « Как мне сделать эту работу, используя Рамду? », если вы не работаете над изучением Рамды. Цели должны включать простоту, ремонтопригодность, производительность и т. Д. c. Если Рамда поможет вам достичь этих целей, отлично. Пропустите это, если это не так.
Запоздалая мысль
Я только что понял, что ни один из вышеперечисленных не обрабатывает полночь правильно. Предположительно, вы хотите, чтобы "00:35"
стал "12:35 AM"
, и это заняло бы незначительную настройку всех версий выше. Первым станет
const formatHour = (time) => {
const [h, m] = time .split (':')
return `${h > 12 ? h - 12 : h == 0 ? 12 : h}:${m} ${h >= 12 ? 'PM' : 'AM'}`
}
И аналогичные изменения необходимо будет применить к другим.