完全外连接在Clojure中的两个地图序列 [英] Full outer join two sequences of maps in Clojure

查看:111
本文介绍了完全外连接在Clojure中的两个地图序列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定:

(def seq1 ({:id 1 :val 10} {:id 2 :val 20}))
(def seq2 ({:id 1 :val 12} {:id 3 :val 30}))


b $ b

在每个序列中,:id 值保证在该序列中是唯一的,但不一定是有序的。

Within each sequence, the :id value is guaranteed to be unique in that sequence, though not necessarily ordered.

如何通过:id 键连接这两个映射序列,以便结果如下所示?

How can these two sequences of maps be joined by the :id key, so that the result is as shown?

{1 [{:id 1 :val 10} {:id 1 :val 12}],
 2 [{:id 2 :val 20} nil            ],
 3 [nil             {:id 3 :val 30}]}

最终的结果是一个对的地图。这类似于一个完整的外连接,其中不仅交集,而且两个集合的差异也包含在输出中。

The ultimate result is a map of pairs. This is similar to a full outer join, where not only the intersection, but also the difference of the two sets is included in the output.

推荐答案

这里是我想出的答案,但我确信它可以更优雅或潜在的更好的性能。

Here's the answer I came up with, however I'm sure it can be made more elegant or potentially to have better performance.

(defn seq-to-map [seq key]
  (into {} (map (fn [{id key :as m}] [id m]) seq)))

(defn outer-join-maps [seq1 seq2 key]
  (let [map1 (seq-to-map seq1 key)
        map2 (seq-to-map seq2 key)
        allkeys (set (clojure.set/union (keys map1) (keys map2)))]
    (into {} (map (fn [k] [k [(get map1 k) (get map2 k)]]) allkeys))))

以下测试通过:

(fact {:midje/description "Sequence to map"}

      (seq-to-map [{:a 1, :b 1} {:a 2, :b 2}] :a)
        => {1 {:a 1, :b 1}, 2 {:a 2, :b 2}}

      (seq-to-map [{:a 1, :b 1} {:a 1, :b 2}] :a)
        => {1 {:a 1, :b 2}} ; takes last value when a key is repeated

      (seq-to-map [] :a)
        => {})

(fact {:midje/description "Sequence merging"}
      (let [seq1 [{:id 1 :val 10} {:id 2 :val 20}]
            seq2 [{:id 1 :val 12} {:id 3 :val 30}]]

        (outer-join-maps seq1 seq2 :id)
          => {1 [{:id 1 :val 10} {:id 1 :val 12}],
              2 [{:id 2 :val 20} nil],
              3 [nil {:id 3 :val 30}]}))

这篇关于完全外连接在Clojure中的两个地图序列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆