我想为地图写一个过滤器函数,它将过滤所有id名称和姓氏道具的给定值。
如果可能的话,我特别需要一个与我的代码相似的过滤器函数代码。我想比较和理解我的错误。如果可能的话,你能和我分享一些其他的想法和方法吗?这对我来说是件好事,当然对将来需要它的社区也是如此。:)
;this is my input map
(def my-map {1 {:id 1 :name "ali" :surname "veli"}
2 {:id 2 :name "batu" :surname "can"}
3 {:id 3 :name "bar" :surname "foo"}
4 {:id 4 :name "zap" :surname "can"}
})
;my expected result for "ba" ---> there are two "ba" value on name prop
{2 {:id 2 :name "batu" :surname "can"}
3 {:id 3 :name "bar" :surname "foo"}}
;my expected result for "ca" ---> there are two "ca" value on surname prop
{2 {:id 2 :name "batu" :surname "can"}
4 {:id 4 :name "zap" :surname "can"}}
;my expected result for "z" ---> there is just one "z" value on surname prop
{4 {:id 4 :name "zap" :surname "can"}}
;This is my search function ---> it is search just on surname at the moment(to find my ;error debugging :))
(defn filter-db-by-surname [?s db]
(->> (for [lenght (range 1 (+ 1 (count my-map)))]
(db lenght))
(filter
(fn
[{:keys [id name surname]} ]
(let [i id
k name
v surname]
(if (str/includes? (str/lower-case (str v)) (str/lower-case (str ?s)))
(into [] {id (my-map i)})
())
)))))
(filter-db-by-surname "ca" my-map
(require '[clojure.string :as str])
(defn filter-map-by-str [data s & fields]
(into (empty data)
(filter (fn [[_k v]]
(some #(str/includes? (% v) s) fields)))
data))
(def my-map {1 {:id 1 :name "ali" :surname "veli"}
2 {:id 2 :name "batu" :surname "can"}
3 {:id 3 :name "bar" :surname "foo"}
4 {:id 4 :name "zap" :surname "can"}
})
(filter-map-by-str my-map "z" :name :surname)
=> {4 {:id 4, :name "zap", :surname "can"}}
您的函数返回所有条目,因为filter
中使用的函数总是返回真值-具有映射条目的向量或空列表。它从不返回false
或nil
,因此没有任何内容被过滤掉。
关于代码的其他注意事项:
- 你的括号格式很奇怪。你应该使用一个合适的编辑器,它会帮你处理。
(+ 1 ...)
是inc
,整个for
循环可以用vals
代替(但我不明白为什么你想要删除你的密钥,当你需要它们的时候)。- 我看不出有任何理由用let引入三个额外的变量,特别是当它们只是你的旧变量,但有更神秘的名字。
- 当
v
和?s
已经是字符串时,为什么要调用(str v)
或(str ?s)
? filter
返回序列-您仍然需要将此结果转换为哈希映射。
简化后的filter-db-by-surname
。注意,此解决方案使用换能器:
(defn filter-db-by-surname [substring db]
(into {}
(filter (fn [[_ {:keys [surname]}]]
(str/includes? (str/lower-case surname)
(str/lower-case substring))))
db))
你也可以用reduce-kv
:
(defn filter-db-by-surname [substring db]
(reduce-kv (fn [m k {:keys [surname] :as v}]
(if (str/includes? (str/lower-case surname)
(str/lower-case substring))
(assoc m k v)
m))
{} db))