【问题标题】:How to distinguish a missing key from a key with value nil in Clojure?如何在 Clojure 中区分缺失的键和值为 nil 的键?
【发布时间】:2016-01-26 00:58:40
【问题描述】:

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

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

这会为包含键 :data 的任何哈希映射生成 42除了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 之前为特殊情况插入额外的列(键)。

【问题讨论】:

  • 呃,(contains? my-hash-map :data)怎么了?

标签: clojure


【解决方案1】:

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

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

当然还有contains?

(contains? {:bar 1} :bar) ; ==> true

【讨论】:

  • contains 很好,因为代码读取为(if (contains? row :data) ...)
【解决方案2】:

如果你只是想测试一个key是否存在,可以使用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!"

【讨论】:

    猜你喜欢
    • 2016-12-04
    • 2022-10-04
    • 1970-01-01
    • 1970-01-01
    • 2011-10-04
    • 2021-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多