map - Clojure:如何将函数应用于 HashMap 中的条目子集?

标签 map clojure hashmap

我不是 Clojure 并试图弄清楚如何做到这一点。

我想创建一个新的哈希映射,它为哈希映射中键的子集将函数应用于元素。做这个的最好方式是什么?

(let 
   [my-map {:hello "World" :try "This" :foo "bar"}]
   (println (doToMap my-map [:hello :foo] (fn [k] (.toUpperCase k)))

这应该会产生一个类似的 map
{:hello "WORLD" :try "This" :foo "BAR"}

最佳答案

(defn do-to-map [amap keyseq f]
  (reduce #(assoc %1 %2 (f (%1 %2))) amap keyseq))

Breakdown:

It helps to look at it inside-out. In Clojure, hash-maps act like functions; if you call them like a function with a key as an argument, the value associated with that key is returned. So given a single key, the current value for that key can be obtained via:

(some-map some-key)

我们想要获取旧值,并通过调用某个函数 f 将它们更改为新值在他们。因此,给定一个键,新值将是:
(f (some-map some-key))

我们希望将这个新值与哈希图中的这个键相关联,“替换”旧值。这就是 assoc做:
(assoc some-map some-key (f (some-map some-key)))

(“替换”是用引号引起来的,因为我们没有改变单个哈希映射对象;每次调用 assoc 时,我们都会返回新的、不可变的、更改的哈希映射对象。这在Clojure,因为哈希映射是持久的,并且在您 assoc 时共享结构。)

我们需要反复assoc新值到我们的 map 上,一次一个键。所以我们需要某种循环结构。我们想要的是从我们的原始哈希映射和单个键开始,然后“更新”该键的值。然后我们获取新的哈希映射和下一个键,并“更新”下一个键的值。我们对每个键重复此操作,一次一个,最后返回我们“累积”的哈希映射。这就是 reduce做。
  • reduce 的第一个参数是一个接受两个参数的函数:一个“累加器”值,它是我们不断“更新”的值;以及在一次迭代中使用的单个参数来进行一些累积。
  • reduce 的第二个参数是作为第一个参数传递给此 fn 的初始值.
  • reduce 的第三个参数是作为第二个参数传递给此 fn 的参数集合, 一次一个。

  • 所以:
    (reduce fn-to-update-values-in-our-map 
            initial-value-of-our-map 
            collection-of-keys)
    
    fn-to-update-values-in-our-map只是 assoc上面的语句,包装在一个匿名函数中:
    (fn [map-so-far some-key] (assoc map-so-far some-key (f (map-so-far some-key))))
    

    所以把它插入reduce :
    (reduce (fn [map-so-far some-key] (assoc map-so-far some-key (f (map-so-far some-key))))
            amap
            keyseq)
    

    在 Clojure 中,有一个写匿名函数的简写:#(...)是匿名 fn由一个表格组成,其中 %1绑定(bind)到匿名函数的第一个参数 %2到第二个等等。所以我们的fn从上面可以等效地写为:
    #(assoc %1 %2 (f (%1 %2)))
    

    这给了我们:
    (reduce #(assoc %1 %2 (f (%1 %2))) amap keyseq)
    

    关于map - Clojure:如何将函数应用于 HashMap 中的条目子集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1638854/

    相关文章:

    java - 从 HashMap 中删除条目

    Java 从 map 中检索自定义键对象

    google-maps - Google Maps API V3 - 如何通过任意航点获得最佳往返路线

    java - 将 map 转换为列表

    Hadoop集群工作

    clojure - 在 Clojure 中将字符串转换为嵌套映射

    clojure - 应用 Clojure

    Emacs htmlize 在批处理模式下?

    java - WeakHashMap的用法?

    java - 为什么我不能初始化 Map<int, String>?