2017-04-07 30 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/