【问题标题】:How do you destructure a map into key-value pairs without knowing the keys in Clojure?如何在不知道 Clojure 中的键的情况下将映射分解为键值对?
【发布时间】:2015-02-09 11:31:37
【问题描述】:

假设我有一张这样的地图

{:a 1 :b 2 :c 3}

我想像这样映射这个(注意 - 非工作伪代码):

(mapcat (fn [[:key key-a][:value value-a]] (println "key: " key-a "\n value: " value-a )))

如果不先获取函数的键、映射这些键并从函数中读取它们,这是否可行?

我的问题是:如何在不知道 Clojure 中键的情况下将映射分解为键值对?

【问题讨论】:

    标签: dictionary clojure destructuring


    【解决方案1】:
    (seq {:a 1 :b 2 :c 3})
    ;([:a 1] [:b 2] [:c 3])
    

    在地图上调用seq 会为您提供一系列键值对。 seq 调用通常是隐式的。

    • 不必按输入的顺序;
    • 实际上是MapEntrys,表现为对。

    这样

    (type (first {:a 1 :b 2 :c 3}))
    ;clojure.lang.MapEntry
    

    你的伪代码

    (mapcat (fn [[:key key-a][:value value-a]] (println "key: " key-a "\n value: " value-a )))
    

    ...需要多次维修:

    • 提供省略的最终参数 - map 的集合 已应用。
    • 只需将每个MapEntry 解构为一对即可获得
      关键和价值。
    • 使用map 而不是mapcat 将函数应用于每一对。 mapcat 能正常工作真是太幸运了。
    • 使用dorun 强制序列进行评估并将其丢弃为 它这样做了。 REPL 为您完成前者,但运行 应用程序不需要。

    这给了我们

    (dorun
     (map 
      (fn [[key-a value-a]] (println "key: " key-a " value: " value-a ))
      {:a 1 :b 2 :c 3}))
    

    打印

    key:  :a  value:  1
    key:  :c  value:  3
    key:  :b  value:  2
    

    ... 返回 nil

    【讨论】:

      【解决方案2】:

      当您在地图上map 时,每个元素都是一个包含两个值的向量:键和值。你用这样的向量解构每个元素:

      (def m {:a 1 :b 2 :c 3})
      (map (fn [[key value]] (str "key: " key " > value: " value-a)) m)
      

      请注意,传递给map 的函数返回一个字符串值,而不是您对println 的调用,因为我们试图通过对每个值应用一个函数来转换传入的集合。您可以将 map 返回的集合传递给 prn 以调试该值,尽管 REPL 无论如何都会为您打印出来。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-06-11
        • 2019-02-24
        • 1970-01-01
        • 2018-11-28
        • 2016-09-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多