简体   繁体   English

在Clojure中,如何映射序列和创建哈希映射

[英]In clojure, how to map a sequence and create a hash-map

In clojure , I would like to apply a function to all the elements of a sequence and return a map with the results where the keys are the elements of the sequence and the values are the elements of the mapped sequence. clojure ,我想将一个函数应用于序列的所有元素,并返回一个包含结果的map ,其中键是序列的元素,而值是映射序列的元素。

I have written the following function function. 我写了以下函数功能。 But I am wondering why such a function is not part of clojure . 但是我想知道为什么这样的功能不是clojure一部分。 Maybe it's not idiomatic ? 也许这不是惯用语言吗?

(defn map-to-object[f lst]
   (zipmap lst (map f lst)))


(map-to-object #(+ 2 %) [1 2 3]) => {1 3, 2 4, 3 5}

Your function is perfectly idiomatic. 您的功能完全是惯用的。

For a fn to be part of core, I think it has to be useful to most people. 要使fn成为核心部分,我认为它必须对大多数人有用。 What is part of the core language and what is not is quite debatable. 什么是核心语言的一部分,哪些不是核心语言,则值得商bat。 Just think about the amount of StringUtils classes that you can find in Java. 考虑一下在Java中可以找到的StringUtils类的数量。

My comments were going to get too long winded, so... 我的评论太冗长了,所以...

  1. Nothing wrong with your code whatsoever. 您的代码没有任何问题。
  2. You might also see (into {} (map (juxt identity f) coll)) 您可能还会看到(into {} (map (juxt identity f) coll))
  3. One common reason for doing this is to cache the results of a function over some inputs. 这样做的一个常见原因是在某些输入上缓存函数的结果。
  4. There are other use-cases for what you have done, eg when a hash-map is specifically needed. 您还可以完成其他用例,例如,当特别需要哈希映射时。
  5. If and only if #3 happens to be your use case, then memoize does this for you. 当且仅当#3恰好是您的用例时,请memoize为您做这件事。

If the function is f , and the resultant map is m then (fx) and (mx) have the same value in the domain. 如果函数为f ,并且结果映射为m(fx)(mx)在域中具有相同的值。 However, the values of (mx) have been precalculated, in other words, memoized. 但是, (mx)的值已预先计算,也就是记住。

Indeed memoize does exactly the same thing behind the scene, it just doesn't give direct access to the map. 实际上,memoment在幕后做的事情完全相同,只是不能直接访问地图。 Here's a tiny modification to the source of memoize to see this. 这是对memoize来源的微小修改,以了解这一点。

(defn my-memoize
  "Exactly the same as memoize but the cache memory atom must
  be supplied as an argument."
  [f mem]
  (fn [& args]
    (if-let [e (find @mem args)]
      (val e)
      (let [ret (apply f args)]
        (swap! mem assoc args ret)
        ret))))

Now, to demonstrate 现在,演示

(defn my-map-to-coll [f coll] 
  (let [m (atom {})
        g (my-memoize f m)]
    (doseq [x coll] (g x))
    @m))

And, as in your example 而且,如您的示例

(my-map-to-coll #(+ 2 %) [1 2 3])
;=> {(3) 5, (2) 4, (1) 3}

But note that the argument(s) are enclosed in a sequence as memoize handles multiple arity functions as well. 但是请注意,自变量同时包含在序列中,因为备忘录也可以处理多个arity函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM