Filtering a dictionary by subject of definitions
Updated answer:

Thanks for clarifying the question, the examples helped. Here is my new attempt:

(defn update-subjects [dict subj]
  (map (fn [[k {val :definitions}]]
         [k {:definitions
             (filter (fn [{s :subject}] 
                       ((into #{} (flatten [s])) subj)) val)}]) dict))

(defn my-filter [dict subj]
  (into {} (-&gt;&gt; (update-subjects dict subj)
                (remove (comp empty? :definitions second)))))

(= (my-filter dictionary "IT") (filter-by-subject dictionary "IT"))
=&gt; true


in this solution, I first remove all the definitions which subjects do not match, and then I remove all the entries with empty definitions. I used the threading macro (->>) for readability.



original answer:

Here is another way of implementing your subject filter:

(defn subject-filter [p m]
   (filter (fn[[k {v :definitions}]]
               (some (fn [{x :subject}] 
                        ((into #{} (flatten [x])) p)) v)) m))


This implementation makes use of two important features:


Destructuring - an idiomatic method of extracting items from a data structure in clojure. I highly recommend keeping the following link handy at all times http://blog.jayfields.com/2010/07/clojure-destructuring.html
Sets as a predicate - in clojure, if a set is in a function position, it acts as a function that returns true iff the first argument is in the set. So it is very idiomatic to write (if (#{1 2 3} i) .. ..) to know if i is either 1, 2 or 3. Perhaps you could even use sets instead of arrays in your data definition for :subject, which will make this code even shorter and faster, and your DS more "correct" - you could never keep two identical subjects and :subject will be a predicate of a query subject.




Just a note, you could also do without so much destructuring, and get a more concise function:

(defn my-filter [p m] 
   (filter (fn[[k v]] (some (fn [x] ((into #{} (flatten [(:subject x)])) p)) (:definitions v))) m))