Clojure: как я могу объединить эти две карты?

У меня есть одна карта, похожая на

{:a {:b {:c {:d [[1 2 3]]}
         :e "Hello"}}}

и еще одна карта, похожая на {:a {:b {:c {:d [[4 5 6]]}}}}. Как я могу объединить эти две карты, чтобы результат выглядел так?

{:a {:b {:c {:d [[1 2 3] [4 5 6]]}
         :e "Hello"}}}

Пожалуйста, добавьте код, который вы пробовали, и причину сбоя (например, ошибки, трассировки стека, журналы и т. д.), чтобы мы могли его улучшить.

cfrick 17.05.2022 13:06
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
Четыре эффективных способа центрирования блочных элементов в CSS
Четыре эффективных способа центрирования блочных элементов в CSS
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то...
1
1
38
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы можете использовать deep-merge-with из устаревшего clojure-contrib.map-utils:

(defn deep-merge-with [f & maps]
  (apply
    (fn m [& maps]
      (if (every? map? maps)
        (apply merge-with m maps)
        (apply f maps)))
    maps))

(def m1
  {:a {:b {:c {:d [[1 2 3]]}
           :e "Hello"}}})

(def m2
  {:a {:b {:c {:d [[4 5 6]]}}}})

(deep-merge-with into m1 m2)
;; => {:a {:b {:c {:d [[1 2 3] [4 5 6]]}
;;             :e "Hello"}}}

Для такого простого варианта использования вы можете придерживаться основных функций Clojure:

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

(dotest
  (let [x    {:a {:b {:c {:d [[1 2 3]]}
                      :e "Hello"}}}
        y    {:a {:b {:c {:d [[4 5 6]]}}}}

        yseq (get-in y [:a :b :c :d])

        r1   (update-in x [:a :b :c :d] into yseq)

        r2   (update-in x [:a :b :c :d] #(into % yseq)) ]

        (is= r1 r2
          {:a {:b {:c {:d [[1 2 3]
                           [4 5 6]]},
                   :e "Hello"}}})))

Как показано для r2, я иногда думаю, что понятнее использовать автономную функцию замыкания, чтобы явно показать, где используется старое значение %. Я часто даже более явно пишу замыкание r2 как:

(fn [d-val]
  (into d-val yseq))

вместо использования макроса чтения #(...).

Другие вопросы по теме