Условно переименовывать ключи в списке и конвертировать в карту? - PullRequest
0 голосов
/ 24 апреля 2019

Есть ли простой способ преобразовать список значений ключей в карту, а также переименовать ключи условным способом?

Пример:

 [{:count 4, :happened "true"} {:count 1, :happened "false"}]

, преобразованный в:

{:happened-count: 4, :didnt-happen-count: 1}

Я немного близок:

user=> (def foo [{:count 4, :happened "true"} {:count 1, :happened "false"}])

user=> (into {} (map (juxt :happened :count) foo))
{"true" 4, "false" 1}

edit: Это работает, но ужасно.Надеясь на что-то более приятное:

(clojure.set/rename-keys (into {} (map (juxt :happened :count) foo)) {"true" :happened-count "false" :didnt-happen-count})

Ответы [ 3 ]

3 голосов
/ 24 апреля 2019

Я бы лучше советовал, используя простое сокращение

(def mapping {"true" :happened-count "false" :didnt-happen-count})

(reduce #(assoc % (-> %2 :happened mapping) (:count %2)) {} data)

;;=> {:happened-count 4, :didnt-happen-count 1}
2 голосов
/ 24 апреля 2019

Если это поможет, вы можете использовать макрос ->>, чтобы увидеть преобразование в виде конвейера:

(->> [{:count 4, :happened "true"} {:count 1, :happened "false"}]
     (map (juxt :happened :count))
     (into {})
     (clojure.set/rename-keys {"true"  :happened-count
                               "false" :didnt-happen-count}))

например. сначала извлеките значения, затем сгруппируйте их в новую карту, затем переименуйте ключи

1 голос
/ 24 апреля 2019

Существует миллион способов решения такой проблемы. Мне нравится быть явным о шагах. Вот как я мог бы подумать об этом:

(ns tst.demo.core
  (:use demo.core tupelo.core tupelo.test))

(dotest
  (let [data       [{:count 4, :happened "true"}
                    {:count 1, :happened "false"}
                    {:count 5, :happened "true"}
                    {:count 3, :happened "false"}]
        data-split (group-by :happened data)
        sum-count  (fn [recs]
                     (reduce +
                       (mapv :count recs)))
        result     {:happened-num     (sum-count (get data-split "true"))
                    :didnt-happen-num (sum-count (get data-split "false"))}]
    (is= data-split
      {"true"  [{:count 4, :happened "true"}
                {:count 5, :happened "true"}],
       "false" [{:count 1, :happened "false"}
                {:count 3, :happened "false"}]} )
    (is= result {:happened-num 9, :didnt-happen-num 4})))

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...