我有一个从clojure-csv输出的序列序列。写Clojure宏来生成映射表格
(def s1 [[:000-00-0000 "SMITH" "JOHN" 27][:000-00-0001 "FARMER" "FANNY" 28]])
我有一个向量列数[0 3],我想用它来从每个序列中提取数据。
与其写一个函数来将可变数量的地图表单压缩在一起,我认为一个宏可能会诀窍。但是,我有麻烦。
这个宏接受一个序列和列“面具”
(defmacro map-cols [seq & columns]
(for [col# columns
:let [mc# `(map #(nth % ~col# nil) ~seq)]]
mc#))
(map-cols s1 cols)
ClassCastException clojure.lang.LazySeq cannot be cast to clojure.lang.IFn bene-csv.core/eval2168
我希望产生在 出现多个映射形式如下:
(zipmap (map #(nth % 0 nil) s1) (map #(nth % 1 nil) s1))
{:000-00-0001 "FARMER", :000-00-0000 "SMITH"}
我希望得到一些我做错了什么想法。当然,我可以根据需要提取的列数调整函数。
谢谢。
编辑:
改性宏
(defmacro map-cols [seq & columns]
(vec (for [col columns
:let [mc `(map #(nth % ~col nil) ~seq)]]
mc)))
(apply zipmap (map-cols s1 cols))
ArityException Wrong number of args (1) passed to: core$zipmap clojure.lang.AFn.throwArity
我不太确定你想让我做什么编辑,所以我编辑了原始问题和输出。谢谢。 – octopusgrabbus 2012-04-17 13:57:50
风格评论:你的:让[mc ...]是多余的。直接产生结果:(对于[col列]'(map#(nth%〜col nil)〜seq)))。至于你的新问题,正如我所说的,zipmap期待着两个参数。就目前来看,你只给出一个,因为你只用一列调用你的宏。 – 2012-04-17 14:02:34
对不起,我无法编译更改。(defmacro map-cols [seq&columns] (vec(for [col columns '(map#(nth%〜col nil)〜seq)]))) – octopusgrabbus 2012-04-17 14:17:44