Reputation: 211
I have been trying to filter complex vector like that
(def mySymbolT [[:name "salary" :type "string" :kind "static" :index 0]
[:name "money" :type "string" :kind "static" :index 1]
[:name "count" :type "int" :kind "field" :index 0]])
My goal is to return the quantity of elements that has the same kind: For example, for kind "static" I expect 2 as an answer. So far I got to write this:
(defn countKind [symbolTable kind]
(count(map first(filter #(= (:kind %) kind) symbolTable))))
Its not working. I must say that I'm new to Clojure and I dont understand well how filter goes with map, so I will be glad to hear explanations. (Yes, I have read the documentation about map and filter, still explanations missing for me, especially when I try to apply to large vectors.)
Upvotes: 0
Views: 260
Reputation: 17849
@Thumbnail is right, it is better to rearrange the form of your data. But in case it comes from elsewhere and you just need to get some data from it several times (especially when the inner lists are quite short: theoretically it is even faster than to convert each one to map and lookup the key), you can avoid converting it into vector of maps like this:
first you can make a function to get property value by name from the vector:
(defn plist-get [look-for items]
(when (seq items)
(if (= look-for (first items))
(second items)
(recur look-for (drop 2 items)))))
and then just use it to get your result:
user> (def data [[:name "salary" :type "string" :kind "static" :index 0]
[:name "money" :type "string" :kind "static" :index 1]
[:name "count" :type "int" :kind "field" :index 0]])
#'user/data
user> (count (filter #(= "static" (plist-get :kind %)) data))
;;=> 2
Upvotes: 1
Reputation: 13483
Your data would be better expressed as an array of maps than of vectors:
(def your-table [{:name "salary", :type "string", :kind "static", :index 0}
{:name "money", :type "string", :kind "static", :index 1}
{:name "count", :type "int", :kind "field", :index 0}])
You can get there from here by ...
(def your-table
(mapv (partial apply array-map) mySymbolT))
Now we can
:kind
as a function to extract those values, andfrequencies
to return what you ask.For example ...
(frequencies (map :kind your-table))
;{"static" 2, "field" 1}
By the way, the Clojure idiom is to hyphenate words in a symbol: my-symbol-t
instead of mySymbolT
.
Upvotes: 4