On Sun, Mar 13, 2011 at 3:50 PM, Alan <a...@malloys.org> wrote:
> Why shouldn't it give '(3 3 3)? It looks like you've introduced a
> fairly arbitrary distinction between the first and second arguments to
> a normally-symmetric function, intersect. And you would get the same
> behavior by using one of my suggestions:
>
> user> (filter (set [1 2 3 3 3]) [3 4 3 5])
> (3 3)
> user> (filter (set [3 4 3 5]) [1 2 3 3 3])
> (3 3 3)

I'm pretty sure what he wants is for the intersection to be "as many
1s as are common to both lists; as many 2s as are common to both
lists; as many 3s ...", so [1 2 3 3 3 4 5] intersect [1 1 3 3 4 6]
would be [1 3 3 4], for instance.

For that sort of thing, what you really want is a "bag" datatype (an
unordered collection with duplicates that is stored and searched more
efficiently than a vector or a list), but here's quick-and-dirty
intersect that does what he wants on anything seqable:

(defn intersect [s1 s2]
  (let [f1 (frequencies s1)
        f2 (frequencies s2)
        d1 (apply dissoc f1 (keys f2))
        d2 (apply dissoc f2 (keys f1))
        f1 (apply dissoc f1 (keys d1))
        f2 (apply dissoc f2 (keys d2))]
    (mapcat
      (fn [[k v]]
        (repeat v k))
      (merge-with min f1 f2))))

user=> (intersect [1 2 3 3 3 4 5] [1 1 3 3 4 6])
(1 3 3 4)
user=> (apply str
         (intersect
           "the quick brown fox jumped over the lazy dog"
           "it was the best of times, it was the worst of times"))
"        abeeeefhhimooorttw"

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to