【问题标题】:In clojure, how to map a sequence and create a hash-map在 clojure 中,如何映射序列并创建哈希映射
【发布时间】:2023-04-08 12:16:01
【问题描述】:

clojure 中,我想对序列的所有元素应用一个函数并返回一个map,其中键是序列的元素,值是映射序列的元素.

我写了以下函数函数。但我想知道为什么这样的功能不是clojure 的一部分。也许它不是惯用的

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


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

【问题讨论】:

  • 这没有错。您可能还会看到(into {} (map (juxt identity f) coll))。核心中的类似功能是memoize,用于常见用例。
  • @A.Webb 您能否详细说明与memoize 的联系?
  • 如果函数是f,而结果映射是m,那么(f x)(m x)lst 域中具有相同的值。但是,(m x) 的值已被预先计算,换句话说,已被记忆。
  • @A.Webb 我正在查看code of memoize,但我没有看到与我的问题相关的任何内容
  • 我无法在评论中给出完整的解释,所以请参阅下面的新答案。

标签: clojure clojurescript


【解决方案1】:

你的函数非常地道。

要使 fn 成为核心的一部分,我认为它必须对大多数人有用。什么是核心语言的一部分,什么不是,这是有争议的。想想你可以在 Java 中找到的 StringUtils 类的数量。

【讨论】:

    【解决方案2】:

    我的 cmets 太啰嗦了,所以...

    1. 您的代码没有任何问题。
    2. 您可能还会看到(into {} (map (juxt identity f) coll))
    3. 这样做的一个常见原因是在某些输入上缓存函数的结果。
    4. 您所做的工作还有其他用例,例如当特别需要哈希映射时。
    5. 当且仅当 #3 恰好是您的用例时,memoize 会为您执行此操作。

    如果函数是f,而结果映射是m,那么(f x)(m x) 在域中具有相同的值。但是,(m x) 的值已被预先计算,换句话说,已被记忆。

    事实上,memoize 在幕后做了完全相同的事情,只是不能直接访问地图。这是对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))))
    

    现在来演示一下

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

    而且,就像你的例子一样

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

    但请注意,参数包含在一个序列中,因为 memoize 也可以处理多个 arity 函数。

    【讨论】:

    • 感谢您的详细解答。我很感激。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多