Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

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)))

question from:https://stackoverflow.com/questions/66058835/why-doesnt-this-keyword-function-lookup-work-in-a-hashmap

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I would try two things. First, print the type of each key. They should all be clojure.lang.Keyword, if the creation code you included is accurate and my-function preserves their type; but if you created it in some other way and misremembered, you might discover that the key is a symbol, or a string or something like that. In general, don't use println on anything but strings, because it's pretty low-fidelity. prn is better at conveying an accurate picture of your data - it's not perfect, but at least you can tell a string from a keyword with it.

Second, look at the printed values more carefully, e.g. with od -t x1 - or you could do it in process with something like:

(let [k (key (first m)), s (name k)]
  (clojure.string/join " " 
                       (for [c s] 
                         (format "%02x" (int c)))))

If the result isn't "53 74 6f 63 6b", then you have some weird characters in your file - maybe nonprinting characters, maybe something that looks like a capital S but isn't, whatever.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...