【问题标题】:Remove nil values from deeply nested maps从深度嵌套的映射中删除 nil 值
【发布时间】:2015-06-04 09:49:33
【问题描述】:

鉴于这张地图:

{:a nil 
   :b {:c nil 
       :d 2 
       :e {:f nil 
           :g 4}}}

我需要一个函数来删除所有的 nil 值,这样返回的地图就是

{:b {:e {:g 4}
     :d 2}}

或者,当给出时:

{:a nil 
   :b {:c nil 
       :d nil 
       :e {:f nil 
           :g nil}}}

结果是:

nil

This question 的答案包含一个据称适用于嵌套地图的函数,但当给定嵌套深度超过一层的地图时,该函数会失败。

【问题讨论】:

    标签: clojure


    【解决方案1】:

    从这里修改答案https://stackoverflow.com/a/22186735/1393248

    
    (defn remove-nils
      "remove pairs of key-value that has nil value from a (possibly nested) map. also transform map to nil if all of its value are nil" 
      [nm]
      (clojure.walk/postwalk 
       (fn [el]
         (if (map? el)
           (not-empty (into {} (remove (comp nil? second)) el))
           el))
       nm))
    

    【讨论】:

    • 您可以将(filter #(second %) el) 更改为(remove (comp nil? second) el) 以处理false 值,例如{:a nil :b false} 将返回 {:b false}
    • @AbbéRésina 如果nils 很少见,那么修改地图会比重建地图更快:(let [m (apply dissoc el (map first (filter (comp nil? second) el)))] ... )
    • 感谢您的更正和建议。我已修复我的代码以仅删除 nil 值的地图条目。
    • 这不会保留记录,除非您使用(and (not (record? el)) (map? el))。当然,您接受不会删除记录的 nil 值。
    【解决方案2】:
    (defn clean [m]
      (if (map? m)
        (let [clean-val (fn [[k v]]
                          (let [v' (clean v)]
                            (when-not (nil? v')
                              [k v'])))
              m' (->> (map clean-val m)
                      (remove nil?)
                      (into {}))]
          (when-not (empty? m') m'))
        m))
    

    【讨论】:

      【解决方案3】:

      使用幽灵你可以这样做:

      (declarepath DEEP-MAP-VALS)
      (providepath DEEP-MAP-VALS (if-path map? [(compact MAP-VALS) DEEP-MAP-VALS] STAY))
      
      (setval [DEEP-MAP-VALS nil?] NONE  
      {:a nil 
        :b {:c nil 
            :d 2 
            :e {:f nil 
            :g 4}}})
      

      请注意,如果没有任何内容,它将返回 :com.rpl.specter.impl/NONE 而不是 nil

      这是this答案的部分重用

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-28
        • 1970-01-01
        • 2012-11-09
        • 2021-08-21
        • 1970-01-01
        • 2012-04-27
        相关资源
        最近更新 更多