如何在Clojure中同时按字符串过滤Map的键值并返回匹配项
在Clojure中实现嵌套Map的键值双匹配过滤
需求说明
对嵌套结构的Map进行过滤,只要内层键(转为字符串后)或对应的值(转为字符串后)包含指定子字符串,就将该键值对以["键字符串" "值字符串"]的形式收集,返回所有符合条件的集合。
输入示例
{1 {:id '1c :race "human" :gender "male"} 2 {:id '1a :race "cat" :gender "cfemale"}}
解决方案
先引入clojure.string工具库,再实现核心过滤函数:
(require '[clojure.string :as str]) (defn filter-map-by-substring [input-map substr] (->> input-map vals ; 提取所有内层Map (mapcat seq) ; 扁平化所有内层键值对 (filter (fn [[k v]] (let [k-str (name k) v-str (str v)] (or (str/includes? k-str substr) (str/includes? v-str substr))))) ; 判断键或值是否包含目标子串 (map (fn [[k v]] [(name k) (str v)])))) ; 转换为要求的向量格式
测试验证
过滤字符串为"c"时:
(filter-map-by-substring {1 {:id '1c :race "human" :gender "male"} 2 {:id '1a :race "cat" :gender "cfemale"}} "c")
输出结果:
(["id" "1c"] ["race" "human"] ["race" "cat"] ["gender" "cfemale"])
过滤字符串为"r"时:
(filter-map-by-substring {1 {:id '1c :race "human" :gender "male"} 2 {:id '1a :race "cat" :gender "cfemale"}} "r")
输出结果:
(["race" "human"] ["race" "cat"] ["gender" "cfemale"] ["gender" "male"])
代码说明
- 扁平化嵌套结构:通过
vals提取外层Map的所有内层Map,再用mapcat seq将每个内层Map转换为键值对序列并合并,得到所有需要处理的键值对。 - 字符串匹配:将关键字类型的键转为字符串(
name函数),任意类型的值转为字符串(str函数),使用str/includes?判断是否包含目标子串。 - 格式转换:将符合条件的键值对转换为
["键" "值"]的向量格式,最终返回序列。
内容的提问来源于stack exchange,提问作者Barış Can Ateş
相关产品推荐
相关产品推荐

