44

assoc-in に似ているが、キーを追加する代わりに削除する関数を作成しようとしています。

(dissoc-in {:a {:b 0}} [:a :b])
;;=> {:a {}}

私はここまで来ました:

(def m {:a {:b {:c 1}}})

(assoc  m :a (assoc (:a m) :b (dissoc (:b (:a m)) :c)))
;;=> {:a {:b {}}}

しかし、ネストされたもの全体が私の頭をいじっています

4

7 に答える 7

114

update-inを使用してこれを記述します。

(update-in {:a {:b 0 :c 1}} [:a] dissoc :b)

=>

{:a {:c 1}}
于 2014-02-21T18:37:49.400 に答える
16

どうですか:

(defn dissoc-in
  "Dissociates an entry from a nested associative structure returning a new
  nested structure. keys is a sequence of keys. Any empty maps that result
  will not be present in the new structure."
  [m [k & ks :as keys]]
  (if ks
    (if-let [nextmap (get m k)]
      (let [newmap (dissoc-in nextmap ks)]
        (if (seq newmap)
          (assoc m k newmap)
          (dissoc m k)))
      m)
    (dissoc m k)))

例:

(dissoc-in {:a {:b 0 :c 1}} [:a :b])

結果:

{:a {:c 1}}

dissoc-inかつては の一部でしたがclojure.contrib.core、現在は の一部ですcore.incubator


空のマップを保持したい場合は、コードを少し変更できます。

(defn dissoc-in
  [m [k & ks :as keys]]
  (if ks
    (if-let [nextmap (get m k)]
      (let [newmap (dissoc-in nextmap ks)]
        (assoc m k newmap))
      m)
    (dissoc m k)))

例:

(dissoc-in {:a {:b {:c 0}}} [:a :b])

結果:

{:a {}}
于 2013-01-23T20:07:47.953 に答える
5

update-in に基づく一般的な解決策は次のとおりです。

(defn dissoc-in [m p]
  (if (get-in m p) 
    (update-in m
               (take (dec (count p)) p)
               dissoc (last p))
    m))
于 2014-10-06T12:09:59.157 に答える
4

ドミニクのコードに触発されています。もっと簡潔なバージョンを書きました

(defn dissoc-in
  [m [k & ks]]
  (if-not ks
    (dissoc m k)
    (assoc m k (dissoc-in (m k) ks))))

(dissoc-in {:a {:b {:c 1}}} [:a :b :c])  ;; => {:a {:b {}}}

別のバージョンdissoc-in2は、空のマップを再帰的に削除します

(defn dissoc-in2
  [m [k & ks]]
  (if-not ks
    (dissoc m k)
    (let [nm (dissoc-in2 (m k) ks)]
      (cond (empty? nm) (dissoc m k)
            :else (assoc m k nm)))))


(ut/dissoc-in {:a {:b {:c 3}}} [:a :b :c]) 
;;; => {:a {:b {}}}

(ut/dissoc-in2 {:a {:b {:c 3}}} [:a :b :c]) 
;;=> {}    
于 2013-01-23T20:39:57.850 に答える
0
(defn dissoc-in [m ks]
  (let [parent-path (butlast ks)
        leaf-key (last ks)]
    (if (= (count ks) 1)
      (dissoc m leaf-key)
      (update-in m parent-path dissoc leaf-key))))
于 2016-12-13T07:40:14.640 に答える