In the app I am working on, I have a number of  pre-computed,cached 
collections, 
and for each collection, I have an accessor function that returns either the 
entire collection or the first n elements.

Currently the underlying collection is a vector, so I had something like this:

(defn foo-accessor
  ([] foo-vector)
  ([n] (take n foo-vector)))

It occurred to me that take returns a list, and so the type returned by my 
accessor was dependent on how it was called,
I thought I would change that, and remembered subvec, so I substituted in 
subvec for take, like this:

                ([n] (subvec foo-vector 0 n))

That worked great until (< (count foo-vector) n), and I got an 
IndexOutOfBoundsException

So, then without thinking much, I wrote 

(defn  subvec-safe
  "subvec fails if you specify an end that is greater than count.  This version 
checks that, and DoesTheRightThing!"
  ([v start]
     (subvec v start))
  ([v start end]
     (if (> (count v)
            end)
       (subvec v
               start
               end)
       (subvec v
               start
               (count v)))))

(Yes, it is safe ONLY for the end value…)

And
(defn takev
   "take for a vector, returns a subvec or the vector itself. Uses subvec-safe 
so specifying a n longer than (count v) works"
   [n vec]
   (subvec-safe vec
                0
                n))

Even before finishing takev, it occurred to me that

(defn- takev
  "take for a vector"
  [n vec]
  (into []
        (take n
              vec)))

Might be easier/faster. 

subvec returns a clojure.lang.APersistentVector$SubVector

whereas (into [] (take …)) returns a vector.

Any thoughts on which of the above is "better"?

Thanks,

Don



-- 
-- 
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
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to