结合并计算两个向量返回的地图Clojure

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了结合并计算两个向量返回的地图Clojure相关的知识,希望对你有一定的参考价值。

我得到了两个向量:[鞋子 牛奶 鞋子]和[1 3 1],我想得到的地图是{鞋子 2,牛奶 3}。鞋子牛奶鞋子]和[1 3 1],我想得到的地图是{鞋子2,牛奶3}。我试着将两个向量进行zipmap,结果只显示出{鞋1奶3}。如果没有循环和迭代,还有其他方法吗?

答案

你也可以采用一种不同的解决方案,为物品对数量对生成单项地图,然后将它们与 +:

(let [goods '[shoes milk shoes]
      amounts [1 3 1]]
  (apply merge-with + (map hash-map goods amounts)))

;;=> {milk 3, shoes 2}
另一答案

你可以用 reduce:

  • 从你的两个列表中建立keyvalue的元组。
  • 累加到地图中:将值加到地图中键的值上(如果缺失,则从0开始(传递nil))。
(let [v1 '[shoes milk shoes]              
      v2 [1 3 1]] 
  (reduce                                                                 
    (fn [m [k v]]                                                   
      (update m k (fnil + 0) v))                        
    {}                     
    (map vector v1 v2)))
; → {shoes 2, milk 3}                                                                                                                                                                     
另一答案

我很喜欢@leetwinski 的解决方案。

实际上,为了解决以后类似的问题,我建议,首先收集列表中所有键的值--按其出现的顺序。

(defn vecs2hash 
  [keys values]
  (apply merge-with concat (map (fn [k v] {k (list v)}) keys values)))

然后:

(def hm (vecs2hash '[shoes milk shoes milk] [1 4 2 3]))

hm
;; => {milk (4 3), shoes (1 2)}

然后,我们可以写一个函数来处理每个收集到的元素,就像你想的那样

定义一个新的函数来对列表中的所有值进行求和。

(defn sum-up-value
  [val]
  (apply + val))

定义一个辅助函数来应用这个辅助函数来处理所有的值列表。

(defn apply-to-each-value
  [fun hm]
  (apply hash-map (interleave (keys hm) (map fun (vals hm)))))

所以在你的例子中:

(apply-to-each-value sum-up-values hm)
;; {milk 7, shoes 3}

以上是关于结合并计算两个向量返回的地图Clojure的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Clojure 中递归展平任意嵌套的向量和映射?

Clojure 中的可插拔向量处理单元

Clojure / Clojurescript:按多个值的地图分组

Clojure 中的可折叠集合是啥?

在 Clojure 中将嵌套向量减少为另一个向量

使用片段的谷歌地图