title: How to take n random items from a collection in Clojure?
body: <p>I have a function that takes n random items from a collection such that the same item is never picked twice. I could accomplish this quite easily:</p>
  
  <pre><code>(defn take-rand [n coll]
    (take n (shuffle coll)))
  </code></pre>
  
  <p>But I have a pesky requirement that I need to return the same random subset when the same seed is provided, i.e.</p>
  
  <pre><code>(defn take-rand [n coll &amp; [seed]] )
  
  (take-rand 5 (range 10) 42L)  ;=&gt; (2 5 8 6 7)
  (take-rand 5 (range 10) 42L)  ;=&gt; (2 5 8 6 7)
  (take-rand 5 (range 10) 27L)  ;=&gt; (7 6 9 1 3)
  (take-rand 5 (range 10))      ;=&gt; (9 7 8 5 0)
  </code></pre>
  
  <p>I have a solution for this, but it feels a bit clunky and not very idiomatic. Can any Clojure veterans out there propose improvements (or a completely different approach)?</p>
  
  <p>Here's what I did:</p>
  
  <pre><code>(defn take-rand
    "Returns n randomly selected items from coll, or all items if there are fewer than n.
    No item will be picked more than once."
    [n coll &amp; [seed]]
    (let [n (min n (count coll))
          rng (if seed (java.util.Random. seed) (java.util.Random.))]
      (loop [out [], in coll, n n]
        (if (or (empty? in) (= n 0))
          out
          (let [i (.nextInt rng n)]
            (recur (conj out (nth in i))
                   (concat (take i in) (nthrest in (inc i)))
                   (dec n)))))))
  </code></pre>