使用矢量动态创建地图

时间:2017-10-11 10:53:21

标签: clojure

我有一个向量[“x”“y”“z”]。

我正在尝试动态创建以下内容:

{:aggs {:bucket-aggregation
        {:terms {:field "x"},
         :aggs {:bucket-aggregation 
                {:terms {:field "y"}, 
                 :aggs {:bucket-aggregation 
                        {:terms {:field "z"}}}}}}}}

我目前有以下内容,但无法弄清楚如何使其递归

(defn testing [terms]
  {:aggs {:bucket-aggregation 
           {:terms {:field (nth terms 0)} (testing (pop terms))}}})

1 个答案:

答案 0 :(得分:1)

这是一种解决方法:

(def my-vec ["x" "y" "z"])

(defn testing [[head & tail]]
  (when head
    {:aggs {:bucket-aggregation (merge {:terms {:field head}}
                                       (testing tail))}}))

(testing my-vec)
;=>
;{:aggs {:bucket-aggregation {:terms {:field "x"},
;                             :aggs {:bucket-aggregation {:terms {:field "y"},
;                                                         :aggs {:bucket-aggregation {:terms {:field "z"}}}}}}}}

这可以通过将输入解构为 head 元素和 tail 元素来实现,因此每次调用都会添加:field head并递归在tail

这是使用reduce来解决的另一种方法:

(reduce
 (fn [acc elem]
   {:aggs {:bucket-aggregation (merge {:terms {:field elem}} acc)}})
 nil
 (reverse my-vec))

这是通过reverse输入向量并从内到外构建地图来实现的。这种reduce方法不会导致大型向量的堆栈溢出,但第一种解决方案将会出现。