Hi Steve,
Although the reduce is very Lispy, in this case it might be clearer
with loop/recur:
(defn random-sample [sample-size items]
(loop [num 0,
current [],
items items]
(if-let [item (first items)]
(if (< num sample-size)
(recur (inc num) (conj current item) (rest items))
(let [index (rand-int num)]
(if (< index sample-size)
(recur (inc num) (assoc current index item) (rest
items))
(recur (inc num) current (rest items)))))
current)))
It could go in clojure.contrib.seq-utils. I'll add it there if you
like.
-Stuart Sierra
On Nov 21, 5:40 pm, "[EMAIL PROTECTED]" <[EMAIL PROTECTED]> wrote:
> I needed a random sampling function for work and wrote this in
> Clojure.
>
> (defn random-sample
> "Take a random sample of size `sample-size' from the `items'
> sequence.
>
> This uses Algorithm R -- random sampling with a reservoir. It
> requires O(`sample-size') space and does not need to know the size of
> `items' ahead of time. Described in Knuth's The Art of Computer
> Programming, volume 2."
> [sample-size items]
> (let [maybe-insert-item
> (fn [[num current] item]
> (if (< num sample-size)
> [(inc num) (conj current item)]
> (let [index (rand-int num)]
> (if (< index sample-size)
> [(inc num) (assoc current index item)]
> [(inc num) current]))))]
> (second (reduce maybe-insert-item [0 []] items))))
>
> It seems to work fine, but it strikes me as a little busy with ()[],
> even for Lisp. Does anyone have any pointers? Will the internal
> function "maybe-insert-item" be evaluated every time "random-sample"
> is called, and if so, is that worth worrying about wrt. program
> optimization?
>
> Does this sort of thing belong in clojure-contrib or somewhere else?
> It seems awfully short but it's a nice function to have, at least for
> me.
>
> Thanks,
> Steve
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---