简体   繁体   English

可以用 2 个键和 Clojure 中的值向量创建一个 map 吗?

[英]is possible to create a map with 2 keys and a vector of values in Clojure?

I am trying to create a program that reads in a table of temperatures from a csv file and would like to access aa collection of temperatures based on the year and day.我正在尝试创建一个程序,该程序从 csv 文件中读取温度表,并希望访问基于年份和日期的温度集合。

the first column stands for the year the tempratures have been recorded.第一列代表记录温度的年份。 the second column stands for a specific day during each month.第二列代表每个月的特定日期。 the rest of the column represent the temperatures each month.该列的 rest 代表每个月的温度。

For example, 2021 - 23 - 119 = 23rd June 2021 has a temperature of 119例如,2021 - 23 - 119 = 2021 年 6 月 23 日的温度为 119

Year   Day      Months from January to December

2018     18  | 45   54  -11  170   99  166  173  177  175   93   74   69

2021     23  | 13   87   75   85   85  119  190  172  156  104   39   53 


2020     23  | 63   86   62  128  131  187  163  162  138  104   60   70 

So far I have managed to load the data from a CSV File with clojure.data.csv .到目前为止,我已经设法从 CSV 文件加载数据clojure.data.csv this returns a sequence of vectors into the program这会将一系列向量返回到程序中

  (defn Load_csv_file  [filepath]
 (try
   (with-open [reader (io/reader filepath)]
     (.skip reader 1)
     ( let [data (csv/read-csv reader)]
       (println  data) )
     )
   (catch Exception ex (println (str "LOL Exception: " (.toString ex))))
   ))

I am currently trying to figure out how to implement this but my reasoning was to create three keys in a map which will take in the year, day and vector of temperatures, to then filter for a specific value.我目前正在尝试弄清楚如何实现这一点,但我的推理是在 map 中创建三个键,这三个键将接受年、日和温度矢量,然后过滤特定值。

Any advice on how i can implement this functionality.关于如何实现此功能的任何建议。

Thanks!谢谢!

i would go with something like this:我会 go 这样的事情:

(require '[clojure.java.io :refer [reader]]
         '[clojure.string :refer [split blank?]]
         '[clojure.edn :as edn])

(with-open [r (reader "data.txt")]
  (doall (for [ln (rest (line-seq r))
               :when (not (blank? ln))
               :let [[y d & ms] (mapv edn/read-string (split ln #"\s+\|?\s+"))]]
           {:year y :day d :months (vec ms)})))

;;({:year 2018,
;;  :day 18,
;;  :months [45 54 -11 170 99 166 173 177 175 93 74 69]}
;; {:year 2021,
;;  :day 23,
;;  :months [13 87 75 85 85 119 190 172 156 104 39 53]}
;; {:year 2020,
;;  :day 23,
;;  :months [63 86 62 128 131 187 163 162 138 104 60 70]})

by the way, i'm not sure csv format allows different separators (as you have in your example.. anyway this one would work for that)顺便说一句,我不确定 csv 格式是否允许使用不同的分隔符(正如您在示例中所使用的那样……无论如何,这个可以解决这个问题)

I would create a map of data that looked something like this我会创建一个 map 的数据,看起来像这样

{2020 {23 {:months [63 86 62 128 131 187 163 162 138 104 60 70]}}}

This way you can get the data out in a fairly easy way (get-in data [2020 23:months]通过这种方式,您可以相当简单地(get-in data [2020 23:months]

So something like this所以像这样

(->> (Load_csv_file "file.csv")
     (reduce (fn [acc [year day & months]] (assoc-in acc [year day] months)) {}))

This will result in the data structure I mentioned now you just need to figure out the location of the data you want这将导致我现在提到的数据结构你只需要弄清楚你想要的数据的位置

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM