计算Clojure中集合的映像是否包含零值


(defn image-of 
"computes the image of the element x under R"
[R x]
(set 
(for [r R] 
(when (= (first r) x) 
(second r)))))

函数思想:当R中的第一个变量等于x时,添加第二个变量。

所以这个函数应该用来计算一个关系的图像。这有点成功。当运行测试时,我得到的结果是:

输入:(image-of #{[1 :a] [2 :b] [1 :c] [3 :a]} 1)

预期:#{:c :a}

实际:#{nil :c :a}

因此,出于某种原因,它包含一个零值。函数中的原因是什么?我想我可以过滤掉任何零值,但希望在一行上有解决方案。

所以问题是我不知道如何使用when这个解决方案做到了:

(set (for [r R 
:when (= (first r) x)] 
(second r)))

让我提出一种不同的方法。

在Clojure中表示关系的自然方式是从键到值集(或其他集合(的映射。将成对集合转换为这种形式的函数是。。。

(defn pairs->map [pairs]
(reduce
(fn [acc [key value]]
(assoc acc key (conj (acc key #{}) value)))
{}
pairs))

例如。。。

(pairs->map #{[1 :a] [2 :b] [1 :c] [3 :a]})
=> {2 #{:b}, 1 #{:c :a}, 3 #{:a}}

您可以将此地图用作函数。如果你给它一个密钥,它会返回相应的值:

({2 #{:b}, 1 #{:c :a}, 3 #{:a}} 1)
=> #{:c :a}

你可以一次性构建这个地图,并根据自己的喜好经常使用它。将其作为函数进行查找实际上是一种恒定的时间操作。但是,每次评估image-of时,都要遍历整个对集合。

最新更新