Search code examples
clojure

Why doesn't this keyword function lookup work in a hashmap?


I guess I need some eyeballs on this to make some sense of this

    (println record)
    (println (keys record) " - " (class record) " : " (:TradeId record) (:Stock record))
    (doall  (map #(println "Key " % "Value " (% record)) (keys record)))

Output:

{:Stock ATT, :AccountId 1, :TradeId 37, :Qty 100, :Price 117, :Date 2011-02-24T18:30:00.000Z, :Notes SPLIT 1:10, :Type B, :Brokerage 81.12}

(:Stock :AccountId :TradeId :Qty :Price :Date :Notes :Type :Brokerage)  -  clojure.lang.PersistentHashMap  :  nil ATT

Key  :Stock Value  ATT
Key  :AccountId Value  1
Key  :TradeId Value  37
...

The issue is (:TradeId record) doesn't work even though it exists as a key. Iterating through all keys and values - Line 3 - yields the right value. Tried renaming the column in the csv but no change in behavior. I see no difference from the other columns (which work) except that this is the first column in the csv.

The hashmap is created from code like this - reading records from a CSV. Standard code from the clojure.data.csv package.

(->> (csv/read-csv reader)
           csv-data->maps
           (map #(my-function some-args %))
           doall))


(defn csv-data->maps 
  "Return the csv records as a vector of maps"
  [csv-data]
  (map zipmap
       (->> (first csv-data) ;; First row is the header
            (map keyword) ;; Drop if you want string keys instead
            repeat)
       (rest csv-data)))


Solution

  • The "first column" thing is definitely suspicous and points to some invisible characters such as a BOM quietly attaching itself to your first keyword.

    To debug try printing out the hex of the names of the keywords. And/or maybe you'll see something if you do a hex dump, e.g., with head -n 2 file.csv | od -x, of the first few lines of the input file.