如何在Clojure中创建动态关键字?

时间:2017-01-09 20:32:58

标签: json clojure

我有一些看起来像这样的JSON:

{"_gallery123abc": "foo" }

但它也可能看起来像这样:

{"_gallery789xyz": "foo" }

在Clojure中有没有办法创建一个关键字来接受正则表达式,这样我才能得到" _gallery"值不管结尾字符? ((keyword #"^_gallery") data) data是{J}的哪一行?

我需要它在链中工作,以便我可以遍历结构,如:(-> data :response :nodes :_gallery :slides :title)

2 个答案:

答案 0 :(得分:1)

我认为为此制定一些效用函数是明智的:

(defn key-like [m k]
  (let [s (name k)]
    (some #(when (clojure.string/starts-with? (name (key %)) s)
             (val %))
          m)))

然后你几乎可以按照你想要的方式使用它:

user> (-> {:a {:b {:_gallery123 {:d "BOOM!"}}}}
          :a
          :b
          (key-like :_gallery)
          :d)
;;=> "BOOM!"

另一种方法是创建一些函数而不是->(如get-in),它可以根据传递的类型检索键。

(defn find-key [m k]
  (if (instance? java.util.regex.Pattern k)
    (some #(when (re-matches k (name (key %)))
             (val %))
          m)
    (get m k)))


(defn get-in+ [m & ks]
  (reduce (fn [curr-val k]
            (if (nil? curr-val) (reduced nil)
                (find-key curr-val k)))
          m ks))

user> (get-in+ {:a {:b {:_gallery123asd {:d "BOOM!"}}}}
               :a
               :b
               #"_gallery\d{3}\w{3}"
               :d)

答案 1 :(得分:0)

尝试使用与正则表达式匹配的键获取值:

DataSource=this.oFacade.Context.Books
                               .Include(c => c.Categories)
                               .AsEnumerable()
                               .Select(c => new dtoObjectDGV
                                            {
                                               ID = c.ID,
                                               Name = c.Name,
                                               CategoryInfo= String.Join(", ", c.Categories.Select(d => d.Name).ToArray())
                                             })
                               .ToList();