检查地图中所有 clojure 值的有效性
Checking validity of all clojure values in a map
是否有一种简洁、惯用的方法来检查映射的所有值是否不为空或 0。
如果我有下面的地图
{"id" 10 "Department" "UI Design" "managerid" 4}
迭代映射值并确保字符串不为空 ("") 或 nil 且 ints/longs 不为 0 或 nil 的最简洁方法是什么。
本质上,我试图在将某些输入提交给数据库之前对其进行验证。我知道我可以使用像 Prismatic/schema 这样的库,但现在我想知道没有这个如何实现它。
此映射仅包含字符串和 ints/longs,但它可以包含其他类型。
有通用的方法吗?
Multimethods 可以为给定问题提供优雅的解决方案:
; 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
几点注意事项:
(not (empty? value))
可以替换为 (not-empty value)
或 (seq value)
,但在这两种情况下,将返回字符串的完整值而不是布尔值(仍将计算为 true
当然)。
- 您不能检查
nil
的数字或字符串,因为 nil
有自己的类型。在上面的示例中,所有 nil
值都被视为无效。如果对于某些键 nils 是可以接受的 - 调度函数 (fn [[k v]] (class v))
应该更改为也考虑到键。
这个解决方案比像
这样的简单函数要长一些
(defn valid? [[k v]]
(cond (string? v) (not (empty? v))
...
:else true))
但它更易于维护和扩展。
编辑。如评论中所述,惯用的方法是使用 (seq coll)
而不是 (not (empty? coll))
,因为 empty? 的定义类似于 (not (seq coll))
。您可能仍想保留 (not (empty? coll))
检查以使验证代码更加明确和明显。
是否有一种简洁、惯用的方法来检查映射的所有值是否不为空或 0。
如果我有下面的地图
{"id" 10 "Department" "UI Design" "managerid" 4}
迭代映射值并确保字符串不为空 ("") 或 nil 且 ints/longs 不为 0 或 nil 的最简洁方法是什么。
本质上,我试图在将某些输入提交给数据库之前对其进行验证。我知道我可以使用像 Prismatic/schema 这样的库,但现在我想知道没有这个如何实现它。
此映射仅包含字符串和 ints/longs,但它可以包含其他类型。
有通用的方法吗?
Multimethods 可以为给定问题提供优雅的解决方案:
; 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
几点注意事项:
(not (empty? value))
可以替换为(not-empty value)
或(seq value)
,但在这两种情况下,将返回字符串的完整值而不是布尔值(仍将计算为true
当然)。- 您不能检查
nil
的数字或字符串,因为nil
有自己的类型。在上面的示例中,所有nil
值都被视为无效。如果对于某些键 nils 是可以接受的 - 调度函数(fn [[k v]] (class v))
应该更改为也考虑到键。
这个解决方案比像
这样的简单函数要长一些(defn valid? [[k v]]
(cond (string? v) (not (empty? v))
...
:else true))
但它更易于维护和扩展。
编辑。如评论中所述,惯用的方法是使用 (seq coll)
而不是 (not (empty? coll))
,因为 empty? 的定义类似于 (not (seq coll))
。您可能仍想保留 (not (empty? coll))
检查以使验证代码更加明确和明显。