Search code examples
clojurenullhashmapkey

Hash-map returns nil for existing key


I have a csv file which i parse using the clojure.data.csv library and turn every row into a map consisting of the field names and the values. The problem is when i try to get the field qid from the first row i get nil even though printing the row does show the hash-map correctly.

(ns exam-system.input.input-csv
  (:require [clojure.data.csv :as csv]
            [clojure.java.io :as io]))

(defn csv-data->maps
  [csv-data]
  (map zipmap
       (->> (first csv-data)
            (map keyword)
            repeat)
       (rest csv-data)))

(with-open [reader (io/reader "mypath\\questions.csv")]
  (doall
   (let [row (first (take 1 (csv-data->maps (csv/read-csv reader))))]
     (println "------------")
     (println row)
     (println (get row :qid))
     (println (contains? row :qid)))))

Console result:

------------
{:qid 11,001, :question With respect to flight spoilers they :, :answer Option A.     Only operate on the ground.                                                                              
Option B.     Only operate in flight.                                                                                 
Option C.     Can operate both on ground and in flight., :cSubmodule 11.9, :correct Option C.     Can operate both on ground and in flight.}
nil
false

The code is mostly identical to the one provided in the library's github page except for the obvious parts. Also i have read this thread but the suggested solution did not apply. All other keys return the appropriate values.

Update: Sample data. These are the first 4 entries in my file. Top being the headers i use to make the map.

qid,question,answer,cSubmodule,correct
"11.001",With respect to flight spoilers they :,"Option A.     Only operate on the ground.                                                                              
Option B.     Only operate in flight.                                                                                 
Option C.     Can operate both on ground and in flight.",11.9,Option C.     Can operate both on ground and in flight.
"11.002",The preferred method of Battery charging a Ni-Cad Battery is constant?,"Option A.     Voltage.                                                                         
Option B.     Current.                                                                             
Option C.     Power.",11.6,Option B.     Current.(CAAIP EEL/1-5 par.4.1)
"11.003","In an aircraft control system, employing servo-tabs installation of external ground locks to main control surface :","Option A.     is unnecessary since system is irreversible and therefore control surface cannot be displace by the wind.                                                                                          
Option B.     would not prevent movement of control column.                                                                                                                           
Option C.     would also prevent movement of control column.",11.9,Option B.     would not prevent movement of control column.(Pallet Anto Flight Control p.222)

Solution

  • Nothing looks obviously wrong with your example, although the usages take 1 and doall are unnecessary. I'm able to get the value from your sample data. I'd suggest leveraging the interactivity provided by the REPL to take this one step at a time and find where it's breaking down:

    (def row-maps (csv-data->maps (csv/read-csv ...)))
    
    (first row-maps) ;; this should print the first row/map to your REPL
    =>
    {:qid "11.001",
     :question "With respect to flight spoilers they :",
     :answer "Option A.     Only operate on the ground.                                                                              
              Option B.     Only operate in flight.                                                                                 
              Option C.     Can operate both on ground and in flight.",
     :cSubmodule "11.9",
     :correct "Option C.     Can operate both on ground and in flight."}
    
    (:qid *1)        ;; *1 will contain the value of the previous evaluation
    => "11.001"