我有两个向量[shoes milk shoes]
和[1 3 1]
,而我想要得到的地图是{shoes 2, milk 3}
。我尝试了zipmap
两个向量,只{shoes 1 milk 3}
显示。没有循环和迭代,还有另一种方法吗?
3 回答
7
您还可以为此采用一些不同的解决方案,为项目到金额对生成单项映射,然后将它们与以下内容合并+
:
(let [goods '[shoes milk shoes]
amounts [1 3 1]]
(apply merge-with + (map hash-map goods amounts)))
;;=> {milk 3, shoes 2}
于 2020-06-05T07:48:31.213 回答
1
我非常喜欢@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}
于 2020-06-06T22:17:20.500 回答
1
你可以这样做reduce
:
- 从您的两个列表中建立键/值元组
- 累积到地图中:将值添加到地图中键的值(如果缺少则从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}
于 2020-06-05T06:55:12.423 回答