在 clojure 中将序列转换为 hashMap
Convert a sequence to hashMap in clojure
我是 clojure 的新手,我正在阅读 csv 并获得如下序列-
[[1501493_raw_html.txt 0]
[1501553_raw_html.txt 0]
[1501589_raw_html.txt 0]
[1501685_raw_html.txt 0]
[1501727_raw_html.txt 0]]
我想将其转换为键值映射,如下所示-
[
{:key 1501493_raw_html.txt :value 0}
{:key 1501553_raw_html.txt :value 0}
{:key 1501589_raw_html.txt :value 0}
...
]
我试过了 -
(def record (interleave [:key :value] (rest read-csv)))
(def arrange-csv-map
;(zipmap [:key :value] read-csv)
(apply hash-map record)
)
(println "Read-csv " (first arrange-csv-map ))
返回输出为-
Read-csv [:key [119_raw_html.txt 0]]
我尝试了一些其他方法,比如
(into {} [:key (first value) :value {rest value}])
但没有像我预期的那样工作。
ABC
Clojure 的 reduce 将为您解决问题:
(def sample [[1501493_raw_html.txt 0]
[1501553_raw_html.txt 0]
[1501589_raw_html.txt 0]
[1501685_raw_html.txt 0]
[1501727_raw_html.txt 0]])
(reduce #(conj %1 (assoc {}
:key (get %2 0)
:value (get %2 1))) [] sample)
这基本上就是在说"For each vector, convert positional elements to respective keys in a new map and accumulate in another vector"
您注释掉的 zipmap
是正确的(interleave
可以,但 zipmap
更简单)。您的两次尝试很可能都失败了,因为您正在处理 read-csv
,我假设,在您的上下文中,它是一个集合或一系列行,而不是一次在一行上。
(zipmap [:key :value] a-line)
对一行进行您想要的转换。现在你必须对所有行执行此操作, map
:
(map (fn [line] (zipmap [:key :value] line)) read-csv)
我认为在这种情况下使用 for
更简单,并且使每个元素到映射的转换更加明显:
(ns ...
(:require [clojure.pprint :refer [pprint] ] ...
(def data-list
[ ["1501493_raw_html.txt" 0]
["1501553_raw_html.txt" 0]
["1501589_raw_html.txt" 0]
["1501685_raw_html.txt" 0]
["1501727_raw_html.txt" 0] ] )
(def result
(for [entry data-list]
{ :key (entry 0)
:value (entry 1) } ))
(pprint result)
给出结果:
> lein run
({:key "1501493_raw_html.txt", :value 0}
{:key "1501553_raw_html.txt", :value 0}
{:key "1501589_raw_html.txt", :value 0}
{:key "1501685_raw_html.txt", :value 0}
{:key "1501727_raw_html.txt", :value 0})
我是 clojure 的新手,我正在阅读 csv 并获得如下序列-
[[1501493_raw_html.txt 0]
[1501553_raw_html.txt 0]
[1501589_raw_html.txt 0]
[1501685_raw_html.txt 0]
[1501727_raw_html.txt 0]]
我想将其转换为键值映射,如下所示-
[
{:key 1501493_raw_html.txt :value 0}
{:key 1501553_raw_html.txt :value 0}
{:key 1501589_raw_html.txt :value 0}
...
]
我试过了 -
(def record (interleave [:key :value] (rest read-csv)))
(def arrange-csv-map
;(zipmap [:key :value] read-csv)
(apply hash-map record)
)
(println "Read-csv " (first arrange-csv-map ))
返回输出为-
Read-csv [:key [119_raw_html.txt 0]]
我尝试了一些其他方法,比如
(into {} [:key (first value) :value {rest value}])
但没有像我预期的那样工作。
ABC
Clojure 的 reduce 将为您解决问题:
(def sample [[1501493_raw_html.txt 0]
[1501553_raw_html.txt 0]
[1501589_raw_html.txt 0]
[1501685_raw_html.txt 0]
[1501727_raw_html.txt 0]])
(reduce #(conj %1 (assoc {}
:key (get %2 0)
:value (get %2 1))) [] sample)
这基本上就是在说"For each vector, convert positional elements to respective keys in a new map and accumulate in another vector"
您注释掉的 zipmap
是正确的(interleave
可以,但 zipmap
更简单)。您的两次尝试很可能都失败了,因为您正在处理 read-csv
,我假设,在您的上下文中,它是一个集合或一系列行,而不是一次在一行上。
(zipmap [:key :value] a-line)
对一行进行您想要的转换。现在你必须对所有行执行此操作, map
:
(map (fn [line] (zipmap [:key :value] line)) read-csv)
我认为在这种情况下使用 for
更简单,并且使每个元素到映射的转换更加明显:
(ns ...
(:require [clojure.pprint :refer [pprint] ] ...
(def data-list
[ ["1501493_raw_html.txt" 0]
["1501553_raw_html.txt" 0]
["1501589_raw_html.txt" 0]
["1501685_raw_html.txt" 0]
["1501727_raw_html.txt" 0] ] )
(def result
(for [entry data-list]
{ :key (entry 0)
:value (entry 1) } ))
(pprint result)
给出结果:
> lein run
({:key "1501493_raw_html.txt", :value 0}
{:key "1501553_raw_html.txt", :value 0}
{:key "1501589_raw_html.txt", :value 0}
{:key "1501685_raw_html.txt", :value 0}
{:key "1501727_raw_html.txt", :value 0})