clojureedn

Clojure - Count occurences of nested key in nested map?


I have a nested map like so:

{:A {:B {:A {:B {:A {:B 0}}}}}}

I want to count the occurrences of the pair [:A :B] so that in the case above, the result is 3.

My initial idea was to use clojure.walk/postwalk to traverse the map and increment a counter.

Is there a more optimal way of achieving this?


Solution

  • tree-seq works out nice in this case:

    (defn count-ab [data]
      (->> data
           (tree-seq coll? seq)
           (keep #(get-in % [:A :B]))
           count))
    
    user> (def data {:A {:B {:A {:B {:A {:B 0}}}}}})
    #'user/data
    
    user> (count-ab data)
    3
    
    user> (def data-1 {:A {:B {:C {:A {:B {:A {:B 0}}}}}}})
    #'user/data-1
    
    user> (count-ab data-1)
    3
    
    user> (def data-2 {:A {:X {:A {:B 100}}
                           :B {:C {:A {:B {:A {:B 0}}}}}}})
    #'user/data-2
    
    user> (count-ab data-2)
    4