Skip to content

Instantly share code, notes, and snippets.

@stuarthalloway
Created March 18, 2010 18:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stuarthalloway/336674 to your computer and use it in GitHub Desktop.
Save stuarthalloway/336674 to your computer and use it in GitHub Desktop.
;; licensed like Clojure, copyright 2010 by Stuart Halloway
(ns
#^{:author "Stuart Halloway"
:doc "Protocols for type-aware collection functions"}
clojure.contrib.collections
(:import [java.util ArrayList Collection]))
(declare slice do-slice)
(defn chop
"Return a collection with the last item removed.
O(1), requires collection is Indexed. Not lazy!"
[coll]
(slice coll 0 (max 0 (dec (count coll)))))
(defn slice
"Return a slice of the collection from start (inclusive)
to end (exclusive). Collection must be Indexed.
Negative indexes are not allowed. O(1). Not lazy!"
([coll start] (slice coll start (count coll)))
([coll start end] (do-slice coll start end)))
(defprotocol Indexed
(join
[c sep]
"Return a new collection of a type similar to c, with each
element of c separated by sep. O(N). Not lazy!")
(do-slice
[c start end]
"Helper fn, clients should call slice directly."))
(extend-protocol Indexed
nil
(join [coll separator] nil)
(do-slice [coll start end] nil)
clojure.lang.PersistentVector
(join
[v separator]
(vec (interpose separator v)))
(do-slice
[s start end]
(let [c (count s)]
(subvec s (min c start) (min c end))))
ArrayList
(join [coll separator]
(ArrayList. #^Collection (interpose separator coll)))
(do-slice
[coll start end]
(let [count (count coll)
end (min end count)
start (min start count)]
(.subList coll start end)))
CharSequence
(join [s separator]
(apply str (interpose separator (str s))))
(do-slice
[s start end]
(let [count (count s)
end (min end count)
start (min start count)]
(.subSequence s start end))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment