我已经定义了一个采用地图的函数。我想用解构来访问这些值。但是,我还想检查是否有任何使用过的密钥。
所以,例如......
(defun func1 [{:keys [a b c] :rest rest}]
(println a b c)
(println rest))
(func1 {:a 1 :b 2 :c 3 :d 4})
会打印
1 2 3
4
我想要这个的原因是如果rest不为null,这可能是一个错误,我想发出信号。我知道:as,我可以使用。但后来我需要存储两次有效密钥列表。
我错过了什么吗?
菲尔答案 0 :(得分:6)
我真的不明白你为什么想知道你有什么事情不关心。如果您正在尝试执行类似“使用这些键执行某些操作,并对其他键执行某些操作”的操作,则可以执行以下操作:
(defn func [& {:keys [a b] :as args}]
(println a b c)
(println (dissoc args :a :b)))
(func :a 3 :b :c 5) =>
3 4
{:c 5}
nil
如果你不得不两次提到这些关键词,你也可能会对此做些什么,但我无法想象它值得打扰。
我想要这个的原因是如果rest不为null,这可能是一个错误,我想发出信号。
如果你担心用户不是完全你想要的,那么地图可能不是正确的数据结构。
答案 1 :(得分:3)
如果您关心对给定地图强制执行结构,Schema
可能是一个不错的选择(来自README
的第一个示例):
(ns schema-examples
(:require [schema.core :as s
:include-macros true ;; cljs only
]))
(def Data
"A schema for a nested data type"
{:a {:b s/Str
:c s/Int}
:d [{:e s/Keyword
:f [s/Num]}]})
(s/validate
Data
{:a {:b "abc"
:c 123}
:d [{:e :bc
:f [12.2 13 100]}
{:e :bc
:f [-1]}]})
;; Success!
(s/validate
Data
{:a {:b 123
:c "ABC"}})
;; Exception -- Value does not match schema:
;; {:a {:b (not (instance? java.lang.String 123)),
;; :c (not (integer? "ABC"))},
;; :d missing-required-key}
答案 2 :(得分:0)
(Phil Lord,OP毫无疑问会转向其他问题,但对于有类似问题的人来说,这是一个可能的解决方案。)
您可以使用count
来测试地图是否具有正确数量的键:
(count {:a 1 :b 2 :c 3 :d 4}) ;=> 4
返回键/值对的数量。只要您单独测试地图是否具有必需的键,就知道有太多的键会告诉您是否还有其他键。
答案 3 :(得分:0)
我喜欢plumbing的做法:
(use '[plumbing.core])
(defnk f1 [a b c & rest]
(prn [a b c])
(prn rest))
(f1 {:a 1 :b 2 :c 66 :z "fake"})
[1 2 66]
{:z "fake"}
=> nil