映射哈希映射中的每个值

rzv*_*rzv 11 clojure hashmap functor

我有一个哈希映射.我想迭代值并根据值的类型替换它们中的每一个.如果该值是整数,请将其替换为true,如果不是,则将其替换为false.我希望这返回一个新的哈希映射,每个值都更新为true或false.

(defn my-function [hash-map]
  (loop [hash-map hash-map]
    (for [value (vals hash-map)]
      (if (= Integer (type value))
        (recur (assoc hash-map key true))
        (recur (assoc hash-map key false))))))
Run Code Online (Sandbox Code Playgroud)

这不会起作用,因为Clojure Can only recur from tail position,但这是我想要做的一般想法.有任何想法的有效方法吗? if-letupdate-in似乎是潜在的解决方案,但我不能完全掌握它们.

kot*_*rak 18

(reduce-kv (fn [m k v] (assoc m k (= Integer (type v)))) {} m)
Run Code Online (Sandbox Code Playgroud)

如果您愿意,甚至更短:

(reduce-kv #(assoc %1 %2 (= Integer (type %3))) {} m)
Run Code Online (Sandbox Code Playgroud)

并保持地图的类型(哈希与排序):

(reduce-kv #(assoc %1 %2 (= Integer (type %3))) (empty m) m)
Run Code Online (Sandbox Code Playgroud)

警告:最后一个不适用于记录.


Mat*_*ick 5

您已经概述的操作 - 独立地转换地图中的每个值 - 实际上已经在Functor模块中实现.

你需要做什么来实现你的功能,转换单个值,然后fmap在你的地图上:

(fmap your-function your-map)
Run Code Online (Sandbox Code Playgroud)

(不要被名称fmap误导 - 这个操作不是特定于地图.因为它是一个通用函数,它适用于任何具有Functor实例的东西,其中还包括列表,集合和向量). 这是一个结构保留操作:不会更改任何键,也不会添加任何新键,也不会删除任何键.

如果您更愿意避免使用泛型函数,请查看实现:

(defmethod fmap clojure.lang.IPersistentMap
  [f m]
  (into (empty m) (for [[k v] m] [k (f v)])))  ;;; <== the important part!!
Run Code Online (Sandbox Code Playgroud)

在哪里f = your-functionm = your-map.


这个库已被移动(正在移动?将被移动?)到clojure.algo.generic.functor.有关详细信息,请参阅内容,以及此内容.