我有一个懒惰的序列,当发送到println
时,显示如下:
(((red dog) (purple cat)) ((green mouse) (yellow bird)))
请注意,这是读取csv并修剪所有“单元格”值的结果,因此(a)在我想要打印它时它很懒,而且(b)将来最里面的列表可能更多超过2个字符串,因为添加了更多列。
我正试图让clojure.pprint/print-table
在两列表中打印出来。我很难过,因为print-table
似乎想要一个map
数据。
这是一个复制品:
;; Mock the lazy data retrieved from a csv file
(defn get-lazy-data []
(lazy-seq '('('("red" "dog") '("purple" "cat")) '('("green" "mouse") '("yellow" "bird")))))
(defn -main []
(let [data (get-lazy-data)]
(println "Starting...")
(println data)
(println "Continuing...")
(print-table data)
(println "Finished!")))
这会出错:
线程“main”中的异常java.lang.ClassCastException:clojure.lang.Symbol无法强制转换为java.util.Map $ Entry
我尝试过各种选择:
(print-table (apply hash-map data))
提供相同的例外(print-table (zipmap data))
告诉我为键提供另一个参数,但我想要一个不依赖于预先指定列数的解决方案基本上我知道我有an XY-problem但现在我想要回答这两个问题:
答案 0 :(得分:3)
如何在控制台上打印一对字符串对的懒惰序列?
你的"行"似乎是成对分组是假的,假设你想要一个双列的颜色/动物表,所以我们可以删除额外的分组mapcat identity
然后zipmap
那些具有所需地图关键字的对:< / p>
(def my-list
'(((red dog) (purple cat)) ((green mouse) (yellow bird))))
(def de-tupled (mapcat identity my-list))
(map #(zipmap [:color :animal] %) de-tupled)
=> ({:color red, :animal dog} {:color purple, :animal cat} {:color green, :animal mouse} {:color yellow, :animal bird})
(clojure.pprint/print-table *1)
| :color | :animal |
|--------+---------|
| red | dog |
| purple | cat |
| green | mouse |
| yellow | bird |
问题不明确,但似乎你想支持任意数量的&#34;列&#34;哪一种排除了他们的固定名称。在这种情况下,你可以这样做:
(def my-list ;; added third mood "column"
'(((red dog happy) (purple cat sad)) ((green mouse happy) (yellow bird sad))))
(def de-tupled (apply concat my-list))
(clojure.pprint/print-table (map #(zipmap (range) %) de-tupled))
| 0 | 1 | 2 |
|--------+-------+-------|
| red | dog | happy |
| purple | cat | sad |
| green | mouse | happy |
| yellow | bird | sad |
如何将延迟序列转换为地图(例如,键是索引)?
(def my-list
'(((red dog) (purple cat)) ((green mouse) (yellow bird))))
(zipmap (range) my-list)
=> {0 ((red dog) (purple cat)), 1 ((green mouse) (yellow bird))}
答案 1 :(得分:0)
与您的问题相关的一点是如何打印数据。 Clojure有两种打印方式:
(dotest
(println ["hello" "there" "everybody"]) ; #1
(prn ["hello" "there" "everybody"])) ; #2
#1 => [hello there everybody]
#2 => ["hello" "there" "everybody"]
对于字符串,#2中引号的存在对理解正在发生的事情有很大的不同。 prn
函数生成机器可读的输出(就像您在源代码中键入的内容一样)。如果您的数据中包含字符串,那么您确实需要这样做。
查看与符号的区别:
(println ['hello 'there 'everybody])
(prn ['hello 'there 'everybody])
; doesn't matter if you quote the whole form or individual symbols
(println '[hello there everybody])
(prn '[hello there everybody])
所有结果都是一样的:
[hello there everybody]
[hello there everybody]
[hello there everybody]
[hello there everybody]
重点是,在打印结果时,需要prn
来区分符号和字符串。请注意,如果您使用prn
,pprint
输出格式(带双引号)会自动发生:
(def data
[["here" "we" "have" "a" "lot" "of" "strings" "in" "vectors"]
["here" "we" "have" "a" "lot" "of" "strings" "in" "vectors"]
["here" "we" "have" "a" "lot" "of" "strings" "in" "vectors"]])
(clojure.pprint/pprint data) =>
[["here" "we" "have" "a" "lot" "of" "strings" "in" "vectors"]
["here" "we" "have" "a" "lot" "of" "strings" "in" "vectors"]
["here" "we" "have" "a" "lot" "of" "strings" "in" "vectors"]]