序列中的可选元素

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,一切都很好!"

以上是关于序列中的可选元素的主要内容,如果未能解决你的问题,请参考以下文章

ES11中的可选链等语法

ES11中的可选链等语法

ListView 中的可选 TextView(缺少动画)

Select2 中的可选 optgroup

Swift:Assert 语句中的可选元组类型

在模板基类中为继承类中的可选覆盖生成虚拟方法