Clojure объединить несколько карт в одну карту

У меня есть следующий список карт

({"child.search" {:roles #{"ROLE_ADM_UNSUBSCRIBE_SUBSCRIPTION" "ROLE_ADM_SEARCH_SUBSCRIPTION" "ROLE_ADM_VIEW_SUBSCRIPTION"}},
  "child.cc.search" {:roles #{"ROLE_ADM_CC_SEARCH_SUBSCRIPTION" "ROLE_ADM_CC_VIEW_SUBSCRIPTION"}}}
  {"child.abusereport" {:roles #{"ROLE_ADM_ABUSE_RPT"}},
   "child.manualfiltering" {:roles #{"ROLE_ADM_MANUAL_FILTERING_RPT"}}}
  {"child.assigned.advertisement" {:roles #{"ROLE_ADM_CREATE_ADVERTISING"}},
   "child.manage.advertisement" {:roles #{"ROLE_ADM_LIST_ADVERTISING"}}})

Мне нужно иметь одну карту, например следующую.

{"child.search" {:roles #{"ROLE_ADM_UNSUBSCRIBE_SUBSCRIPTION" "ROLE_ADM_SEARCH_SUBSCRIPTION" "ROLE_ADM_VIEW_SUBSCRIPTION"}}
"child.cc.search" {:roles #{"ROLE_ADM_CC_SEARCH_SUBSCRIPTION" "ROLE_ADM_CC_VIEW_SUBSCRIPTION"}}
"child.abusereport" {:roles #{"ROLE_ADM_ABUSE_RPT"}}
"child.manualfiltering" {:roles #{"ROLE_ADM_MANUAL_FILTERING_RPT"}}
"child.assigned.advertisement" {:roles #{"ROLE_ADM_CREATE_ADVERTISING"}}
"child.manage.advertisement" {:roles #{"ROLE_ADM_LIST_ADVERTISING"}}}

Как я могу это сделать?

Ответ 1

Вы можете использовать функцию into и предоставить пустую карту {} в качестве первый аргумент:

(into {} map-list)

Здесь вывод из моего сеанса REPL; Я скопировал ваш код в два списка карт "map" и "single-map" (Clojure 1.3.0):

(def map-list '({"child.search" {:roles #{"ROLE_ADM_UNSUBSCRIBE_SUBSCRIPTION" "ROLE_ADM_SEARCH_SUBSCRIPTION" "ROLE_ADM_VIEW_SUBSCRIPTION"}},
                 "child.cc.search" {:roles #{"ROLE_ADM_CC_SEARCH_SUBSCRIPTION" "ROLE_ADM_CC_VIEW_SUBSCRIPTION"}}}
                {"child.abusereport" {:roles #{"ROLE_ADM_ABUSE_RPT"}},
                 "child.manualfiltering" {:roles #{"ROLE_ADM_MANUAL_FILTERING_RPT"}}}
                {"child.assigned.advertisement" {:roles #{"ROLE_ADM_CREATE_ADVERTISING"}},
                 "child.manage.advertisement" {:roles #{"ROLE_ADM_LIST_ADVERTISING"}}}))

#'user/map-list
user=>
(def single-map {"child.search" {:roles #{"ROLE_ADM_UNSUBSCRIBE_SUBSCRIPTION" "ROLE_ADM_SEARCH_SUBSCRIPTION" "ROLE_ADM_VIEW_SUBSCRIPTION"}}
                 "child.cc.search" {:roles #{"ROLE_ADM_CC_SEARCH_SUBSCRIPTION" "ROLE_ADM_CC_VIEW_SUBSCRIPTION"}}
                 "child.abusereport" {:roles #{"ROLE_ADM_ABUSE_RPT"}}
                 "child.manualfiltering" {:roles #{"ROLE_ADM_MANUAL_FILTERING_RPT"}}
                 "child.assigned.advertisement" {:roles #{"ROLE_ADM_CREATE_ADVERTISING"}}
                 "child.manage.advertisement" {:roles #{"ROLE_ADM_LIST_ADVERTISING"}}})
#'user/single-map

user=>
;; Check to see if we have the desired result
(= (into {} map-list)
   single-map)
true

Ответ 2

Я бы, вероятно, использовал merge и apply

(def map-list (list {:a 1, :b 2} {:c 3, :d 4}))
(apply merge map-list) ;; returns {:a 1, :b 2, :c 3, :d 4}

Ответ 3

Попробуйте это

(def your-list '({"child.search" {:roles #{"ROLE_ADM_UNSUBSCRIBE_SUBSCRIPTION" "ROLE_ADM_SEARCH_SUBSCRIPTION" "ROLE_ADM_VIEW_SUBSCRIPTION"}},
  "child.cc.search" {:roles #{"ROLE_ADM_CC_SEARCH_SUBSCRIPTION" "ROLE_ADM_CC_VIEW_SUBSCRIPTION"}}}
  {"child.abusereport" {:roles #{"ROLE_ADM_ABUSE_RPT"}},
   "child.manualfiltering" {:roles #{"ROLE_ADM_MANUAL_FILTERING_RPT"}}}
  {"child.assigned.advertisement" {:roles #{"ROLE_ADM_CREATE_ADVERTISING"}},
   "child.manage.advertisement" {:roles #{"ROLE_ADM_LIST_ADVERTISING"}}}))

(reduce conj your-list)

Ответ 4

В этом ответе разъясняется, как "в" и "соединить" взаимосвязаны в этом случае, чтобы обеспечить приемлемые решения вашей проблемы. То есть, он стоит на плечах предыдущих ответов.

У вас есть список, который имеет формат:

( {key1 value1} 
  {key2 value2} ) 

И вам нужна карта, которая извлекла пары ключ/значение следующим образом:

{key1 value1, key2 value2} 

Проблема заключается в том, что вы, по сути, хотите "объединить" каждую последовательную пару k/v в последнюю, на одной карте.

Первое решение выше использует это. Если мы посмотрим на clojuredoc, мы увидим:

"Возвращает новый столбец, состоящий из-to-coll со всеми элементами из-coll соединены."

Другой, похожий ответ - использовать

(reduce conj '({key1 value1} {key2 value2}))

Ясно, что это решение описывает определение "в" выше для этой проблемы: функция уменьшения накапливает каждое приложение сопряжения пары значений nth + (nth + 1th), так что оно реализует определение в (по крайней мере, для целей этого вопроса).