检查映射中所有clojure值的有效性
是否有一种干净、惯用的方法来检查映射的所有值是否为空或0 例如,如果我有以下地图检查映射中所有clojure值的有效性,clojure,Clojure,是否有一种干净、惯用的方法来检查映射的所有值是否为空或0 例如,如果我有以下地图 {"id" 10 "Department" "UI Design" "managerid" 4} 迭代映射值并确保字符串不为空(“”)或nil以及int/long不为0或nil的最干净方法是什么 本质上,我试图在将输入提交到数据库之前验证它。我知道我可以使用像Prismatic/schema这样的库,但现在我想知道没有它如何实现 此映射仅包含字符串和int/long,但可以包含其他类型 有没有一种通用的解决方法?
{"id" 10 "Department" "UI Design" "managerid" 4}
迭代映射值并确保字符串不为空(“”)或nil以及int/long不为0或nil的最干净方法是什么
本质上,我试图在将输入提交到数据库之前验证它。我知道我可以使用像Prismatic/schema这样的库,但现在我想知道没有它如何实现
此映射仅包含字符串和int/long,但可以包含其他类型
有没有一种通用的解决方法?可以为给定的问题提供优雅的解决方案:
; for now dispatch is based only on value type
(defmulti valid? (fn [[k v]] (class v)))
(defmethod valid? java.lang.Long [[_ value]] (not (zero? value)))
(defmethod valid? java.lang.String [[_ value]] (not (empty? value)))
(defmethod valid? nil [_] false)
(defmethod valid? :default [_] true) ; valid for rest cases
要查看整个地图,请执行以下操作:
(every? valid? your-map)
示例:
(every? valid? {:a 1 :b 0}) ; false
(every? valid? {:a 1 :b 1}) ; true
(every? valid? {:a 1 :b ""}) ; false
(every? valid? {:a 1 :b "a"}) ; true
(every? valid? {:a 1 :b "a" :c []}) ; true
几点注意:
可以替换为(非(空?值))
或(非空值)
,但在这两种情况下,将返回字符串的完整值,而不是布尔值(当然,布尔值仍将计算为(seq value)
)true
- 您不能检查
的数字或字符串,因为nil
有自己的类型。在上面的示例中,所有nil
值都被视为无效。如果对于某些密钥,零是可接受的-调度功能nil
应更改为也考虑密钥(fn[[k v]](第五类))
(defn valid? [[k v]]
(cond (string? v) (not (empty? v))
...
:else true))
但它更易于维护和扩展
编辑。正如注释中提到的,惯用的方法是使用(seq coll)
而不是(not(empty?coll))
,因为它的定义类似于(not(seq coll))
。您可能仍然希望保持(而不是(空?coll))
检查,以使验证代码更加明确和明显。可以为给定问题提供优雅的解决方案:
; for now dispatch is based only on value type
(defmulti valid? (fn [[k v]] (class v)))
(defmethod valid? java.lang.Long [[_ value]] (not (zero? value)))
(defmethod valid? java.lang.String [[_ value]] (not (empty? value)))
(defmethod valid? nil [_] false)
(defmethod valid? :default [_] true) ; valid for rest cases
要查看整个地图,请执行以下操作:
(every? valid? your-map)
示例:
(every? valid? {:a 1 :b 0}) ; false
(every? valid? {:a 1 :b 1}) ; true
(every? valid? {:a 1 :b ""}) ; false
(every? valid? {:a 1 :b "a"}) ; true
(every? valid? {:a 1 :b "a" :c []}) ; true
几点注意:
可以替换为(非(空?值))
或(非空值)
,但在这两种情况下,将返回字符串的完整值,而不是布尔值(当然,布尔值仍将计算为(seq value)
)true
- 您不能检查
的数字或字符串,因为nil
有自己的类型。在上面的示例中,所有nil
值都被视为无效。如果对于某些密钥,零是可接受的-调度功能nil
应更改为也考虑密钥(fn[[k v]](第五类))
(defn valid? [[k v]]
(cond (string? v) (not (empty? v))
...
:else true))
但它更易于维护和扩展
编辑。正如注释中提到的,惯用的方法是使用
(seq coll)
而不是(not(empty?coll))
,因为它的定义类似于(not(seq coll))
。您可能仍然希望保持(not(empty?coll))
检查以使验证代码更加明确和明显。说明:“请使用惯用语(seq x)而不是(not(empty?x))”,因为(empty?coll)
定义为(not(seq coll))
(not(empty?x))将运行(not(not(seq x))
)。有些人喜欢(不是(空的?x))
,但官方的说法是(seq x)
是惯用的方式。@Mars谢谢。我在答案中添加了这一点。答案是:“请使用成语(seq x)而不是(not(empty?x))”,因为(empty?coll)
被定义为(not(seq coll))
——所以(not(empty?x))
将运行(not(not(seq x))
)。有些人喜欢(不是(空的?x))
,但官方的说法是(seq x)
是惯用的方式。@Mars谢谢。我在答案中加了这个。