如何过滤映射上的值并返回结果



我想为地图写一个过滤器函数,它将过滤所有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中使用的函数总是返回真值-具有映射条目的向量或空列表。它从不返回falsenil,因此没有任何内容被过滤掉。

关于代码的其他注意事项:

  • 你的括号格式很奇怪。你应该使用一个合适的编辑器,它会帮你处理。
  • (+ 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))

相关内容

  • 没有找到相关文章

最新更新