简体   繁体   English

使用Spectre转换与键匹配的值

[英]Using specter to transform values that match a key

I'm sorry if this has been answered elsewhere, but I can't seem to find an example that matches the pattern of what I'm looking for. 很抱歉,如果在其他地方都回答了这个问题,但是我似乎找不到与我所寻找的模式相匹配的示例。 I also may not yet understand recursive specter paths fully. 我可能还没有完全理解递归幽灵路径。

If I have the data (explicitly with the nested vector): 如果我有数据(显式使用嵌套向量):

{:a "1" :b "2" :c [ {:a "3" :b "4"} {:a "5" :b "6"} ]}

And I'd like to apply the keyword function to all values with the key :a to result in: 我想通过keyword :akeyword函数应用于所有值,以得出:

{:a :1 :b "2" :c [ {:a :3 :b "4"} {:a :5 :b "6"} ]}

Finally, I'd like it to be recursive to an arbitrary depth, and handle the vector case as well. 最后,我希望它可以递归到任意深度,并且也可以处理向量情况。

I've read https://github.com/nathanmarz/specter/wiki/Using-Specter-Recursively , but I must be missing something critical. 我已经阅读了https://github.com/nathanmarz/specter/wiki/Using-Specter-Recursively ,但是我必须缺少一些重要的东西。

Thanks to anyone pointing me in the right direction! 感谢任何指向我正确方向的人!

(use '[com.rpl.specter])
(let [input          {:a "1" :b "2" :c [{:a "3" :b "4"} {:a "5" :b "6"}]}
      desired-output {:a :1 :b "2" :c [{:a :3 :b "4"} {:a :5 :b "6"}]}
      FIND-KEYS      (recursive-path [] p (cond-path map? (continue-then-stay [MAP-VALS p])
                                                     vector? [ALL p]
                                                     STAY))]

    (clojure.test/is
        (= (transform [FIND-KEYS (must :a)] keyword input)
           desired-output)))

Not a Specter solution, but it is easily done via clojure.walk/postwalk : 这不是Spectre解决方案,但可以通过clojure.walk/postwalk轻松完成:

(ns demo.core
  (:require
    [clojure.walk :as walk] ))

(def data    {:a "1" :b "2" :c [{:a "3" :b "4"} {:a #{7 8 9} :b "6"}]})
(def desired {:a :1  :b "2" :c [{:a :3  :b "4"} {:a #{7 8 9} :b "6"}]})

(defn transform
  [form]
  (if (map-entry? form)
    (let [[key val] form]
      (if (and
            (= :a key)
            (string? val))
        [key (keyword val)]   ; can return either a 2-vector
        {key val}))           ; or a map here
    form))

(walk/postwalk transform data) => 

    {:a :1, :b "2", :c [{:a :3, :b "4"} {:a #{7 9 8}, :b "6"}]}

I even put in a non-string for one of the :a values to make it trickier. 我什至为:a值之一添加了非字符串,以使其更加棘手。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM