简体   繁体   English

Clojure:实现关联函数

[英]Clojure: Implementing the assoc-in function

Chapter 5, Exercise 3 in Clojure for the Brave and True requires: 第 5 章,Clojure for the Brave and True 练习 3要求:

Implement the assoc-in function.实现关联函数。 Hint: use the assoc function and define its parameters as [m [k & ks] v] .提示:使用assoc函数并将其参数定义为[m [k & ks] v]

Although I have found this solution (see lines 39-54), I wondered if there was a different way of doing it.虽然我找到了这个解决方案(参见第 39-54 行),但我想知道是否有不同的方法。 When working on the previous exercise, I found this very clear answer by jbm on implementing the comp function to be very helpful.在进行上一个练习时,我发现 jbm 关于实现 comp 功能的这个非常明确的答案非常有帮助。

I've been trying to reduce a partial assoc over a conjoined list of keys and apply the returned function to the final value:我一直在尝试减少键的联合列表上的部分关联,并将返回的函数应用于最终值:

(defn my-part-assoc [m k]
  (partial assoc m k))

((reduce my-part-assoc {} [:one :two :three]) "val")

Needless to say, this doesn't work.不用说,这是行不通的。 I am new to Clojure and functional programming and fear my very basic understanding of reduce is leading me down the wrong path.我是 Clojure 和函数式编程的新手,我担心我对 reduce 的基本理解会导致我走错路。 Please can someone provide a more concise answer?请问有人可以提供更简洁的答案吗?

Shortly after posting, I found this , which gets the following definition from the Clojure GitHub repo :发布后不久,我发现了这个,它从Clojure GitHub 存储库中获得了以下定义:

(defn assoc-in
  ;; metadata elided
  [m [k & ks] v]
  (if ks
    (assoc m k (assoc-in (get m k) ks v))
    (assoc m k v)))

Here is a solution that doesn't use "assoc-in" which seems to be a requirement:这是一个不使用“assoc-in”的解决方案,这似乎是一个要求:

(defn my-assoc-in
  [m [k & ks] v]
  (if (= (count ks) 0)
    (assoc m k v)
    (let [ordered-ks (reverse ks)
          first-m (get-in m (butlast (cons k ks)))]
      (assoc m k (reduce
                  (fn [curr-m next-k] (assoc {} next-k curr-m))
                  (assoc first-m (first ordered-ks) v)
                  (rest ordered-ks))))))```

I think Ooberdan's idea works in case of:我认为 Ooberdan 的想法适用于以下情况:

(defn my-as-in 
  "assoc val in nested map with nested key seq"                                
  [mp [ky & kysq] val]                                                          
  (if kysq                                                                     
    (assoc mp ky (my-as-in (get mp ky) kysq val))                                  
    (assoc mp ky val)))   

(my-as-in {} [:is :this :hello] 1)

gives {:is {:this {:hello 1}}} same as assoc-in ...给出{:is {:this {:hello 1}}}assoc-in ...

Seems neat and idiomatic Clojure and it showed me the way after I got lost in reduce or multi arity type solutions.看起来整洁且惯用的 Clojure,它向我展示了在我迷失在reduce或 multi arity 类型解决方案中的方式。

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

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