2012-11-03 24 views
6

我定義了一個需要映射的函數。我想使用解構來訪問這些值。但是,我也想檢查是否有任何使用的密鑰。clojure中的解構圖 - 未使用的密鑰

因此,例如像...

(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 

,我想這是,如果剩下的就是不爲空,這可能是一個錯誤的原因,我想表示。我知道:作爲,我可以使用。但後來我需要存儲有效密鑰的列表兩次。

我錯過了什麼嗎?

菲爾

回答

5

我真的不明白,爲什麼你會永遠想知道是否有你不關心反正事情。如果你試圖做一些事情,如「做具體的與這些鍵的東西,並做一些通用與其他」你可以這樣做:如果你是偏執不得不提的關鍵詞兩次

(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 

,你也可以做一些這方面的事情,但我無法想象這是值得的麻煩。

,我想這是,如果剩下的就是不爲空,這可能是一個錯誤,我想它的信號的原因。

如果您是關注用戶傳遞不準確你想要什麼,也許一個地圖是不正確的數據結構使用。

+0

我的邏輯是,如果他們通過了錯誤的鍵,這可能是一個錯誤。我使用了一張地圖,因爲它似乎是一個足夠明智的選擇。不知道什麼是更好的選擇。該功能需要取任意數量(包括無)的一組定義參數。你會建議什麼數據結構? –

+1

當然,在這種情況下Map仍然是最好的,但我仍然不明白爲什麼你會限制自己(或者更確切地說:你的用戶!)。這不一定是他們傳遞了「錯誤」的鍵,而是他們有一個更大的屬性映射,而這些屬性並不一定只針對你的函數。 – Cubic

+0

啊,是的,這是真的。我正在實施什麼是DSL。因此,在這種情況下,這些值很可能是由用戶直接編寫的,而不是從別處生成的。所以他們不太可能擁有大型屬性地圖。如果他們這樣做,那麼他們總是可以使用選擇鍵來解決我的限制。 –

1

如果你關心執行的結構給定的地圖,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} 
0

(菲爾主,OP無疑轉移到其他問題,但是這是一個有類似問題的人一個可能的解決方案)

你可以使用count測試地圖是否有按鍵的右側數:

(count {:a 1 :b 2 :c 3 :d 4}) ;=> 4 

這將返回鍵/值對的數量。只要你分別測試地圖是否有所需的密鑰,知道密鑰太多會告訴你是否還有其他密鑰。

+1

不錯的主意,但它不能解決我的問題,因爲你假設你必須通過所有的關鍵。我也需要能夠傳遞他們的一些密鑰,但不是錯誤的。最後,我走了一條不同的路線,並沒有通過解構來做到這一點,因爲我需要更加豐富的論證處理。 –

+0

啊,我明白了。也許這會幫助別人。 – Mars

+0

的確,感謝您發佈這個想法! –