Chris Murphy
Chris Murphy

Reputation: 6509

Clojure, contains?/get on a set

contains? tells you whether get will succeed. I would also like to think that get returns something that comes from the collection, in this case a set.

(def all-match-okay #{
                 #{[3 0] [0 5]}
                 #{[2 4] [0 5]}})

(defn joinable? [b1 b2]
  (let [in-a-set (set [b1 b2])
        res (contains? all-match-okay in-a-set)]
    res))

(defn join [b1 b2]
  (let [in-a-set (set [b1 b2])
        res (get all-match-okay in-a-set)]
    (first res)))

(defn -main
  [& args]
  (println (joinable? [0 5] [3 0]))
  (println (join [0 5] [3 0]))
  )  

If you run the above code then true will come back from joinable? but [0 5] will come back from join. This means that what is in the collection is not being returned, but rather what got the match.

I'm sure what is happening here is theoretically correct (after all if they match it should not matter which is returned). But on the other hand returning what is actually in the set would also be theoretically fine. Would it not?

Upvotes: 1

Views: 352

Answers (1)

cfrick
cfrick

Reputation: 37008

The problem is the (first res) call. You get a random element of the set, since they are not ordered. An (hopefully repeatable) example:

(second (apply hash-set (range 32)))
=> 7 (instead of 1)

clojure.core comes with a sorted set. thirdparty libs (like e.g. flatland) provide ordered sets.

Upvotes: 2

Related Questions