序列中的可选元素
Posted
技术标签:
【中文标题】序列中的可选元素【英文标题】:Optional element in sequence 【发布时间】:2016-03-26 06:37:51 【问题描述】:我正在尝试使用 Prismatic/Schema 匹配以下序列:
[:n "some text"] ; => valid
和
[:k "some text" :n "some text"] ; => valid
我尝试过的:
(s/def Elem3
:k s/Str)
(s/def Elem2
:n s/Str)
(s/def Elem
[(s/optional Elem2 "elem2") Elem3])
(s/validate Elem [:k "huji"])
;; =>
;; Value does not match schema: [(named :n missing-required-key, :k
;; disallowed-key "elem2")]
(s/def Elem
[(s/maybe Elem2) Elem3])
(s/validate Elem [:k "huji"])
;; =>
;; [(maybe :n Str) :k java.lang.String] is not a valid sequence
;; schema; a valid sequence schema consists of zero or more `one`
;; elements, followed by zero or more `optional` elements, followed by
;; an optional schema that will match the remaining elements.
(s/defrecord ElemOption1
[elem3 :- Elem3])
(s/defrecord ElemOption2
[elem2 :- Elem2
elem3 :- Elem3])
(s/def Elem
(s/conditional
#(= 2 (count %)) ElemOption2
:else ElemOption1))
(s/validate Elem [:k "huji"])
;; =>
;; Value does not match schema: (not (instance?
;; peg_dsl.standard_app.ElemOption1 [:k "huji"]))
主要问题是我不明白写的方式是什么 允许省略指定向量的第一个元素的模式。 从上面匹配两个向量的正确方法是什么?
【问题讨论】:
【参考方案1】:您第一次尝试的问题是,从
optional 意味着它期望 :k s/Str 或什么都没有,它正在看到
:n s/Str
,这显然是不对的。
您的第二次尝试有两个问题。 Maybe
可以是值
或nil
,但它必须存在。你也没有写
正确排序模式。但是序列模式的问题
元素是否需要按s/one* s/optional*
的顺序排列,而您
想要s/optional s/one
。
你的第三次尝试更接近,使用条件,但你 未能匹配,因为您没有验证 记录,您正在验证地图。
解决方案如下所示:
(def ElemKNList [(s/one :k s/Str "k") (s/one :n s/Str "n")])
(def ElemNList [(s/one :n s/Str "n")])
(def Elem (s/conditional #(= 2 (count %)) ElemKNList
:else ElemNList))
(s/validate Elem [:k "huji" :n "huji"])
=> [:k "huji" :n "huji"]
(s/validate Elem [:n "huji"])
=> [:n "huji"]
(s/validate Elem [:k "huji"])
=> ExceptionInfo Value does not match schema: [(named :n missing-required-key, :k disallowed-key "n")] schema.core/validator/fn--18435 (core.clj:151)
【讨论】:
我在第一次尝试中期望做的是 Schema 说:“我期望一个序列由可选的 :ns/Str 和一个 :ks/Str 组成。当我验证 [:k "huji"] 时,我看到 :ns/Str 不存在但随后变为 :ks/Str,一切都很好!"以上是关于序列中的可选元素的主要内容,如果未能解决你的问题,请参考以下文章