2017-04-07 31 views
0

我想在clojure的大型地图中更改某些关键点。 这些钥匙可以出现在地图上的任何级别,但总是在要求钥匙内关于所选关键字的Clojure烤肉串案例

我在使用camel-snake-kebab库,但需要它只更改所需的一组给定的键键地图。如果变化在JSON或地图

(def my-map {:allow_kebab_or-snake {:required-key {:must_be_kebab ""}} 
      :allow_kebab_or-snake2 {:optional-key {:required-key {:must_be_kebab ""}}}}) 

目前使用/步行/ postwalk替换,但担心它可能会改变不嵌套键进行的并不重要:需要关键词表

(walk/postwalk-replace {:must_be_kebab :must-be-kebab} my-map)) 

回答

0

ummmm ..你能澄清一下:你想改变地图的钥匙?!或他们的相关值?

题外话:你上面的图是不正确的(有两个相同的密钥:allow_kebab_or_snake - IM假设你刚刚强调的一点,而不是显示实际例子:))

postwalk替换将取代任何键值与值的出现。

所以如果你知道确切的地图结构,你可以先用GET-在选择子结构,然后用postwalk替换:

(walk/postwalk-replace {:must_be_kebab :mus-be-kebab} 
         (get-in my-map [:allow_kebab_or_snake :required-key])) 

但随后你必须assoc这为您的初始地图。

如果交错DS过于复杂,您还应该考虑漫游功能并构建您自己的特定算法。

+0

谢谢,我需要改变的钥匙,烤肉情况下,JSON有效载荷在蛇情况下有它们,但需要烤羊肉串。编辑问题以澄清事情 –

0

这是一个解决方案。由于您需要控制转换何时/不会发生,因此您不能仅使用postwalk。您需要实现自己的递归,并在发现条件时从非转换 - >转换中更改上下文。

(ns tst.clj.core 
    (:use clj.core clojure.test tupelo.test) 
    (:require 
    [clojure.string :as str] 
    [clojure.pprint :refer [pprint]] 
    [tupelo.core :as t] 
    [tupelo.string :as ts] 
)) 
(t/refer-tupelo) 
(t/print-versions) 

(def my-map 
    {:allow_kebab_or-snake {:required-key {:must_be_kebab ""}} 
    :allow_kebab_or-snake2 {:optional-key {:required-key {:must_be_kebab ""}}}}) 

(defn children->kabob? [kw] 
    (= kw :required-key)) 

(defn proc-child-maps 
    [ctx map-arg] 
    (apply t/glue 
    (for [curr-key (keys map-arg)] 
     (let [curr-val (grab curr-key map-arg) 
      new-ctx (if (children->kabob? curr-key) 
         (assoc ctx :snake->kabob true) 
         ctx) 
      out-key (if (grab :snake->kabob ctx) 
         (ts/kw-snake->kabob curr-key) 
         curr-key) 
      out-val (if (map? curr-val) 
         (proc-child-maps new-ctx curr-val) 
         curr-val)] 
     {out-key out-val})))) 

(defn nested-keys->snake 
    [arg] 
    (let [ctx {:snake->kabob false}] 
    (if (map? arg) 
     (proc-child-maps ctx arg) 
     arg))) 

最终结果在单元测试中示出:

(is= (nested-keys->snake my-map) 
    {:allow_kebab_or-snake 
    {:required-key 
     {:must-be-kebab ""}}, 
    :allow_kebab_or-snake2 
    {:optional-key 
     {:required-key 
     {:must-be-kebab ""}}}})) 

对于这种溶液我使用的一些的便利功能in the Tupelo library.

0

只是场建议的左其可能或可能不工作。这是在处理SQL数据库时可能出现的问题,因为' - '被视为保留字并且不能用于标识符。但是,在使用clojure时,在关键字中使用' - '是很常见的。在clojure中使用SQL时使用的许多抽象层将映射作为准备语句的参数/绑定等。

理想情况下,需要的是另一层抽象,根据需要根据您的方向在烤肉串和蛇壳之间进行转换即即将到SQL或从SQL。此形式给出的优点是你无法通过地图进行转换走 - 你做对飞”在需要时转换”

看一看https://pupeno.com/2015/10/23/automatically-converting-case-between-sql-and-clojure/