Dictionary Clojure-过滤最内层的嵌套映射
过滤以下嵌套映射并保持嵌套映射结构的最佳方法是什么。在我的示例中,Alice和Bob可以复制,例如,同一名员工可以同时在多个不同的工厂工作Dictionary Clojure-过滤最内层的嵌套映射,dictionary,filter,clojure,Dictionary,Filter,Clojure,过滤以下嵌套映射并保持嵌套映射结构的最佳方法是什么。在我的示例中,Alice和Bob可以复制,例如,同一名员工可以同时在多个不同的工厂工作 (def universe {:customer1 {:plant1 { "Alice" {:age 35 :sex "F"} "Bob" {:age 25 :sex "M"}} :plant2 {}} :customer2 {} }) 例如,我想按年龄>30过滤并返回相同的地图结构。理想情况下
(def universe
{:customer1
{:plant1
{ "Alice" {:age 35 :sex "F"}
"Bob" {:age 25 :sex "M"}}
:plant2 {}}
:customer2 {}
})
例如,我想按年龄>30过滤并返回相同的地图结构。理想情况下,这将适用于任何嵌套贴图深度,在最内层进行过滤。预期结果:
(def universe
{:customer1
{:plant1
{ "Alice" {:age 35 :sex "F"}
}
:plant2 {}}
:customer2 {}
})
我已经看过了,但它似乎没有解决我的问题。谢谢,这与前面的一个问题非常相似:
(use '[com.rpl.specter])
(let [input {:customer1
{:plant1
{"Alice" {:age 35 :sex "F"}
"Bob" {:age 25 :sex "M"}}
:plant2 {}}
:customer2 {}}
desired-output {:customer1
{:plant1 {"Alice" {:age 35 :sex "F"}}
:plant2 {}}
:customer2 {}}
RECUR-MAP (recursive-path [] p (cond-path map? (continue-then-stay [MAP-VALS p])))]
(clojure.test/is (= (setval [RECUR-MAP (pred :age) #(> 30 (:age %))] NONE input)
desired-output)))
感谢@akond的回答,阅读代码让我想到了一个非幽灵解决方案。不过,有点惊讶的是,在这个用例中没有简单的方法来应用
过滤器
(defn recursive-filter [pred k m]
(letfn [(pair-filter [pair] (if (pred (k (second pair))) pair nil))]
(into {}
(for [a m]
(if (empty? (second a))
[(first a) {}]
(if (contains? (second a) k)
(pair-filter a)
[(first a) (recursive-filter pred k (second a))]))))))
您的数据有点不寻常,因为人们通常期望:customer1
,:customer2
等在向量中是不同的条目。对于这样的半结构化数据,我会考虑<代码> PASSWORK< <代码>:
(ns tst.demo.core
(:use tupelo.core demo.core tupelo.test)
(:require
[clojure.walk :as walk] ))
(def universe
{:customer1
{:plant1
{"Alice" {:age 35 :sex "F"}
"Bob" {:age 25 :sex "M"}}
:plant2 {}}
:customer2 {}})
(def age-of-wisdom 30)
(defn wisdom-only
[form]
(let [filter-entry? (when (map-entry? form)
(let [[-name- details] form
age (:age details)] ; => nil if missing
(and age ; ensure not nil
(< age age-of-wisdom))))]
(if filter-entry?
{}
form)))
(walk/postwalk wisdom-only universe) =>
{:customer1
{:plant1
{"Alice" {:age 35, :sex "F"}}
:plant2 {}}
:customer2 {}}
(ns tst.demo.core
(:使用tupelo.core demo.core tupelo.test)
(:需要
[clojure.walk:as walk]))
(定义宇宙)
{:客户1
{:工厂1
{“爱丽丝”{:35岁:性别“F”}
“鲍勃”{:25岁:性别“M”}
:plant2{}
:customer2{})
(智慧时代30)
(只有智慧
[表格]
(让[筛选条目](何时(地图条目?表格)
(让[[-姓名-详细信息]表格
年龄(:年龄详细信息);=>如果缺少,则为零
(b)年龄;确保不为零
(智慧时代)
(如果是筛选条目?
{}
表格))
(行走/行走后智慧专属宇宙)=>
{:客户1
{:工厂1
{“爱丽丝”{:35岁,性别“F”}
:plant2{}
:customer2{}
如果您还显示了所需的输出,那就太好了。