2017-10-11 2 views
1

J'ai un vecteur ["x" "y" "z"].Créer dynamiquement une carte en utilisant le vecteur

Je suis en train de créer dynamiquement les éléments suivants:

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

J'ai actuellement les éléments suivants, mais ne peut pas comprendre comment le rendre récursif

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

Répondre

1

est ici une façon de résoudre:

(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"}}}}}}}} 

Cela fonctionne en déstructurant l'entrée dans une tête élément et queue éléments, de sorte que chaque appel ajoute un :field de head et récursif sur le tail.

Et voici une autre façon de résoudre en utilisant reduce:

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

Cela fonctionne en reverse ing le vecteur d'entrée et la construction de la carte de l'intérieur vers l'extérieur. Cette approche reduce n'entraînera pas de débordement de pile pour les grands vecteurs, mais la première solution le fera.