4

我们经常测试哈希映射是否存在某个键,例如:data,通过针对 测试对该键的值的试验检索nil,如

(defn test-my-hash-map [my-hash-map]
  (if (:data my-hash-map) 42 "plugh!"))

这会42为包含:data具有任何值的键的任何哈希映射生成,除了value nil

(map test-my-hash-map
     [{:data "Hello!"}    ; ~~> 42
      {:no-data "Yikes!"} ; ~~> "plugh!"
      {:data nil}         ; ~~> "plugh!", but I need it to say 42 :(
     ])

我根本看不到有任何方法可以做到这一点,这会弄乱一些数据处理场景,在这些场景中,我们从非 Clojure 源获取数据,其中缺少的键意味着“我在那个键上没有数据”和带有nil值的键意味着“我那里有数据,但无论出于何种原因我都无法将其提供给您”。我看不到在 Clojure 代码中区分这些情况的方法。我非常讨厌的解决方法是插入一个 Java shim,它可以检测差异并在移交给 Clojure 之前为特殊情况插入额外的列(键)。

4

2 回答 2

5

有一个 clojure 函数get允许提供默认值。

(:foo {:bar 1}) ; ==> nil
(get {:bar 1} :foo "no key inserted") ; ==> "no key inserted"

当然也有contains?

(contains? {:bar 1} :bar) ; ==> true
于 2013-09-21T01:14:59.583 回答
2

如果您只想测试密钥是否存在,可以使用contains?

(contains? {:a nil} :a) ; => true
(contains? {:a nil} :b) ; => false

在您的情况下,您可以提供默认值get

(get {:a 42} :a "foo!") ; => 42
(get {:a nil} :a "foo!") ; => nil
(get {:a 42} :b "foo!") ; => "foo!"
于 2013-09-21T01:16:18.960 回答