首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Clojure在验证中使用来自另一个必需键的值

Clojure在验证中使用来自另一个必需键的值
EN

Stack Overflow用户
提问于 2018-05-05 11:38:12
回答 1查看 101关注 0票数 2

我是clojure的新手,我正在寻找一种方法来使用一个必需键的值来验证另一个键。我可以通过使用这两个值创建另一个映射并传递它来实现,但我希望有一种更简单的方法。谢谢

代码语言:javascript
复制
(s/def ::country string?)
(s/def ::postal-code   
  ;sudo-code
  ;(if (= ::country "Canda")
  ;(re-matches #"^[A-Z0-9]{5}$") 
  ;(re-matches #"^[0-9]{5}$"))
)

(s/def ::address
  (s/keys :req-un [
    ::country
    ::postal-code
    ::street
    ::state
  ]))
EN

回答 1

Stack Overflow用户

发布于 2018-05-05 18:44:33

这里有一种使用multi-spec实现的方法

代码语言:javascript
复制
(defmulti country :country)
(defmethod country "Canada" [_]
  (s/spec #(re-matches #"^[A-Z0-9]{5}$" (:postal-code %))))
(defmethod country :default [_]
  (s/spec #(re-matches #"^[0-9]{5}$" (:postal-code %))))

(s/def ::country string?)
(s/def ::postal-code string?)
(s/def ::address
  (s/merge
    (s/keys :req-un [::country ::postal-code])
    (s/multi-spec country :country)))

(s/explain ::address {:country "USA" :postal-code "A2345"})
;; val: {:country "USA", :postal-code "A2345"} fails spec: :sandbox.so/address at: ["USA"] predicate: (re-matches #"^[0-9]{5}$" (:postal-code %))
(s/explain ::address {:country "Canada" :postal-code "A2345"})
;; Success!

另一个选项是and-ing您的keys规范上的另一个谓词:

代码语言:javascript
复制
(s/def ::address
  (s/and
    (s/keys :req-un [::country ::postal-code])
    #(case (:country %)
       "Canada" (re-matches #"^[A-Z0-9]{5}$" (:postal-code %))
       (re-matches #"^[0-9]{5}$" (:postal-code %)))))

您可能更喜欢multi-spec方法,因为它可以扩展,也就是说,您可以稍后为country定义更多的defmethod,而不是将所有逻辑都保留在and谓词中。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50185480

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档