我是新来的。我的问题是如何得到两个散列映射的交集。
(def map-1 {"a" 2, "b" 1, "c" 4, "d" 3})
(def map-2 {"a" 3, "b" 6, "e" 5})由于我们定义了两个映射,预期的结果将是{"a" 3, "b" 6},它位于一个具有交叉键和键的最大值的映射中。
不知何故,我想出了一个解决方案,并实现了它,但它的工作原理部分正确。
其基本思想是找出地图中项目数量最少的地图,作为参考。对于参考地图中的每个项,以检查另一个映射是否包含它。如果包含,则将键放入输出映射及其最大值(使用(max num1 num2))。
下面是我的示例代码:
(defn max-intersect [map1 map2]
(let [smaller-map (if (< (count map1) (count map2))
map1
map2)
longer-map (if (= smaller-map map1)
map2
map1)]
(loop [output {}
reference-map smaller-map]
(if (empty? reference-map)
output
(recur (let [[item-key item-val] (first smaller-map)]
(when (contains? longer-map item-key)
(assoc output item-key (max item-val (get longer-map item-key)))))
(rest reference-map))))))这是我后悔的结果:
test-intersect.core=> (def map1 {"a" 2, "b" 1, "c" 4, "d" 3})
#'test-intersect.core/map1
test-intersect.core=> (def map2 {"a" 3, "b" 6, "e" 5})
#'test-intersect.core/map2
test-intersect.core=> (max-intersect map1 map2)
{"a" 3}这似乎很复杂,我也在等待任何伟大和有效的解决方案。
非常感谢!
发布于 2018-03-13 09:54:49
这可以使用merge-with使用max作为合并函数来完成:
(def map-1 {"a" 2, "b" 1, "c" 4, "d" 3})
(def map-2 {"a" 3, "b" 6, "e" 5})
(merge-with max map-1 map-2)
=> {"a" 3, "b" 6, "c" 4, "d" 3, "e" 5}merge-with类似于merge,但它允许传递一个函数,以便在两个映射中出现一个键时选择合并的值。
若要只包含两个映射中出现的键,则可以将select-keys与两个映射键的集合交集一起使用:
(select-keys (merge-with max map-1 map-2)
(clojure.set/intersection
(set (keys map-1))
(set (keys map-2))))发布于 2018-03-13 10:07:20
(require '[clojure.set :refer [intersection]])
(defn merge-with-max-intersecting
[m1 m2]
(let [intersecting (intersection (set (keys m1))
(set (keys m2)))]
(merge-with max
(select-keys m1 intersecting)
(select-keys m2 intersecting))))
(merge-with-max-intersecting {"a" 2, "b" 1, "c" 4, "d" 3}
{"a" 3, "b" 6, "e" 5})
;;=> {"a" 3, "b" 6}发布于 2018-03-13 12:20:05
您也可以这样一次通过:
(defn merge-maps [m1 m2]
(reduce-kv (fn [acc k v]
(if (contains? m1 k)
(assoc acc k (max v (m1 k)))
acc))
{}
m2))
user> (merge-maps map-1 map-2)
;;=> {"a" 3, "b" 6}https://stackoverflow.com/questions/49252956
复制相似问题