簡體   English   中英

在Clojure中有沒有找到地圖中匹配鍵和值的慣用方法?

[英]Is there an idiomatic way to find matching key and value in map in Clojure?

我正在嘗試從地圖中找到匹配的鍵和值對。 我正在使用以下代碼:

(defn matches? [m k v]
  (let [val (k m)]
    (= val v)))

my-demo.core=> (matches? {:a 1 :b 2} :b 2)
true
my-demo.core=> (matches? {:a 1 :b 2} :b 3)
false

使用superset?另一種方法superset?

my-demo.core=> (superset? #{:a 1 :b 3} #{:a 1})
true
my-demo.core=> (superset? #{:a 1 :b 3} #{:a 2})
false

我覺得有一種更好的方法可以做到這一點。

我的問題是: 在Clojure中是否有一種慣用的方法可以在地圖中找到匹配的鍵和值?

這可能是一個小問題,你可以使用它而不是定義一個函數:

(= ({:a 1 :b 2} :a)
   1)

=> true

我會說這是一種慣用的方式,對於大多數用例來說都可以正常工作。


但是,它取決於測試nil值時所需的行為。 因為上面的方法會返回true :c nil

(= ({:a 1 :b 2} :c)
   nil)

=> true

並且您的函數的行為方式相同:

(matches? {:a 1 :b 2} :c nil)

=> true

為了解決這個問題,你可以使用get了“未找到”值:

(= (get {:a 1 :b 2} :c ::not-found)
   nil)

=> false

這工作正常,但它可能不是很整潔。 您只需要確保您的“未找到”值永遠不會與您的測試值相同。


如果你想真正知道一個地圖包含一個可能nil值的密鑰,你將不得不檢查兩件事。 這是一個只執行一次哈希映射查找的函數。 它使用(find map key)返回(find map key)的映射條目(鍵值對),如果鍵不存在則返回nil。

(defn contains-kv? [m k v]
  (if-let [kv (find m k)]
    (= (val kv) v)
    false))

(contains-kv? {:a 1 :b nil} :a 1)
=> true

(contains-kv? {:a 1 :b nil} :b nil)
=> true

(contains-kv? {:a 1 :b nil} :c nil)
=> false

注意:我不認為superset? 正在做你認為它做的事情。 在該示例中,您使用的是集合,而不是哈希映射,它們完全不同:

(clojure.set/superset? #{:a 1 :b 2} #{:a :b})

=> true

你的matches? 函數看起來不錯,雖然我可能會在這種情況下刪除let,因為它消除了一些混亂。 我還將它重命名為更精確的東西,盡管這是我現在能想到的最好的東西:

(defn contains-kv?
  "Returns true if the key k is present in the given map m and it's value matches v."
  [m k v]
  (= (m k) v))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM