#clojure
#clojure
Вопрос:
Итак, у меня есть моя предлагаемая zip-карта, и она отлично работает. Как вы можете видеть, у меня есть загрузка данных.
Вот как это выглядит в repl, который является идеальным. И прямо здесь находится карта
:Year 2020, :Day 27, :January 59, :February 38
:Year 2020, :Day 28, :January 41, :February 57
:Year 2020, :Day 29, :January 56, :February 51
:Year 2020, :Day 31, :January 94, :February -999
:Year 2020, :Day 30, :January 76, :February -999
(map [:Day :Month
Имейте в виду, что это всего лишь фрагмент кода, который я сделал. Как бы вы предложили мне найти день с наибольшим значением в январе? И под наибольшим я подразумеваю число рядом с месяцами
(into(sorted-map-by >(fn [:January]))Ha)
Я безуспешно пытался это сделать, «Ha» в конце — это просто имя функции, в которой я инициализирую zipmap и использую io / reader для чтения файла
Комментарии:
1. Проще, если вы не используете
zipmap
. Возьмите cols 0,1,2, найдите max в col 2, затем извлеките day. Повторите для столбцов 0,1,3 (февраль). и т.д.2. Есть ли причина, по которой zipmap сложнее?
Ответ №1:
Я бы использовал max-key и уменьшил:
(def data [{:Year 2020, :Day 27, :January 59, :February 38}
{:Year 2020, :Day 28, :January 41, :February 57}
{:Year 2020, :Day 29, :January 56, :February 51}
{:Year 2020, :Day 31, :January 94, :February -999}
{:Year 2020, :Day 30, :January 76, :February -999}])
(reduce (partial max-key :January) data)
;; => {:Year 2020, :Day 31, :January 94, :February -999}
(:Day (reduce (partial max-key :January) data))
;; => 31
Комментарии:
1. Не могли бы вы дать мне небольшое объяснение относительно того, что делают обе функции, я не хочу брать на борт то, чего я не понимаю, хотя это очень хороший ответ 🙂
2. Обе функции довольно просты для понимания. Используйте ссылки в моем ответе, чтобы получить доступ к документации, прочитать, что они делают, и попробовать их самостоятельно в REPL. Я должен упомянуть, что
reduce
это очень практично для обработки последовательностей. По сути(reduce f [1 2 3 4])
, вычисляется(f (f (f 1 2) 3) 4)
как .3. Будет сделано, спасибо 🙂
4. Хороший вызов — я никогда
max-key
раньше не использовал. Хотя я бы выбралapply
вместоreduce
.5. @AlanThompson, вы правы: не нужно беспокоиться о сокращении частичном, когда вы можете просто сделать
(apply max-key :January data)
Ответ №2:
Не уверен, как выглядит ваша точная структура данных, но, предполагая, что это вектор карт, вы можете сделать что-то вроде этого:
(def data
[{:Year 2020, :Day 27, :January 59, :February 38}
{:Year 2020, :Day 28, :January 41, :February 57}
{:Year 2020, :Day 29, :January 56, :February 51}
{:Year 2020, :Day 31, :January 94, :February -999}
{:Year 2020, :Day 30, :January 76, :February -999}])
(->> data
(sort-by :January)
last
:January)
;; => 94
Сортировка вектора с помощью ключевого слова в качестве функции для поиска его значения на карте, затем взятие вектора с наибольшим значением за январь, затем получение значения, принадлежащего ключу :January
, из этого вектора. Дайте мне знать, если ваша структура данных выглядит немного иначе.
Комментарии:
1. Да, моя структура данных точно такая, но в файле, из которого я ее загружаю, просто еще один быстрый вопрос: как бы вы также вернули год и день, с которого был получен самый высокий январь? Я пытался повысить ваш ответ, но моя учетная запись довольно новая, поэтому она не позволит мне :/
2. @Codemosh Вы можете выбрать несколько ключей, например
juxt
, применив к результату несколько функций (ключевых слов), которые вы хотите. Используя тот жеmax-key
подход, что и выше (apply max-key f
в основном такой же, как->> sort-by f last
, возможно, только с немного лучшей производительностью), вы получаете((juxt :Year :Day :January :February) (apply max-key :January m)) ;; => [2020 31 94 -999]
.3. @Codemosh Или вы можете использовать
let
привязку и деструктировать ключи следующим образом(let [{:keys [Year Day January February]} (apply max-key :January m)] [Year Day January February]) ;; => [2020 31 94 -999]
.
Ответ №3:
ответ @Rule очень хороший. Без max-key
этого было бы:
(def data [{:Year 2020, :Day 27, :January 59, :February 38}
{:Year 2020, :Day 28, :January 41, :February 57}
{:Year 2020, :Day 29, :January 56, :February 51}
{:Year 2020, :Day 31, :January 94, :February -999}
{:Year 2020, :Day 30, :January 76, :February -999}])
(defn seq-max [seq greater key]
(reduce (fn [a b] (if (greater (key a) (key b)) a b)) seq))
;; if no key is wanted, choose the function `identity` as key!
;; e.g.
;; (seq-max (map :January data) > identity)
;; => 94
(:Day (seq-max data > :January)) ;; => 31