(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
时,都要遍历整个对集合。