我有一个向量定义表中的列,如下所示
(def column [“col1”“col2”“col3”“col4”])
然后几个向量定义列的类型和约束。
(def maxInclude [nil nil 1000 nil])
(def minInlcude [nil 200 300 nil])
(def columntype [int float int int])
然后我需要得到如下的映射:一个映射条目定义每个列,key是列名,value是该列的类型和约束。
{:col1 {:columntype "int"},
:col2 {:columntype "float" :minInlcude 200},
:col3 {:columntype "float" :minInlcude 300 :maxInclude 1000},
:col4 {:columntype "int" }
}
怎么做?
答案 0 :(得分:1)
我建议你将columntype
定义为符号的向量而不是函数,所以:
(def columntype ['int 'float 'int 'int])
而不是:
(def columntype [int float int int])
另请注意,minInlcude
拼写错误,我已将其重命名为minInclude
。您可以使用以下命令创建结果(minInclude已重命名,columntype是符号的向量):
(def column ["col1" "col2" "col3" "col4"])
(def maxInclude [nil nil 1000 nil])
(def minInclude [nil 200 300 nil])
(def columntype ['int 'float 'int 'int])
(defn remove-nil-vals [m]
(into {} (map (fn [e]
(vector (key e)
(into {} (remove (comp nil? val) (val e)))))
m)))
(remove-nil-vals
(reduce merge
(map #(hash-map (keyword %1) {:columntype (str %2)
:minInclude %3
:maxInclude %4})
column columntype minInclude maxInclude)))
{:col4 {:columntype "int"},
:col3 {:columntype "int", :minInclude 300, :maxInclude 1000},
:col2 {:columntype "float", :minInclude 200},
:col1 {:columntype "int"}}
符号的Clojure命名约定是连字符而不是CamelCase。因此,您应该考虑使用max-include
代替maxInclude
。
答案 1 :(得分:1)
解决此问题的一种方法是同时映射所有向量。但是,您需要为地图密钥指定特定名称(例如columntype
等),因此以下解决方案并非通用:
(defn- constraints [cname type min max]
{(keyword cname)
(as-> {:columntype (str type)} cmap
(if min
(assoc cmap :minInclude min)
cmap)
(if max
(assoc cmap :maxInclude max)
cmap))})
这基本上构建了每个"行"的结果。在结果地图中。这里需要注意的是Clojure类型int和float到字符串之间的映射。我想你真的不想对Clojure类型有约束。如果我是对的,您可能应该更改columntype
中的数据以使用关键字(即:int, :float
)并从上面的str
更改为name
。
然后你可以使用mapv
映射所有向量,从每个向量中同时获取第一个值,然后是第二个值,依此类推,并将其提供给constraints
函数:
(mapv constraints column maxInclude minInclude columntype)
这是一个示例运行:
user> (pprint (into {} (mapv constraints column columntype maxInclude minInclude)))
{:col1 {:columntype "clojure.core$int@607af697"},
:col2 {:maxInclude 200, :columntype "clojure.core$float@4e8b32fb"},
:col3
{:maxInclude 300,
:minInclude 1000,
:columntype "clojure.core$int@607af697"},
:col4 {:columntype "clojure.core$int@607af697"}}
nil