diff options
author | Rich Hickey <richhickey@gmail.com> | 2008-06-20 21:23:43 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2008-06-20 21:23:43 +0000 |
commit | 4299c7689ac0238d5cfc388d260a400022f53a05 (patch) | |
tree | 7be14439cbc4b8ca7a3fd8dbb8a526da3c6c4b27 /src | |
parent | 7774621725227f70473c6e42c6d96585bb644d0a (diff) |
nth takes an optional not-found value, and destructuring uses nth with a nil not found value for sequential destructuring, nth without not-found value throws exception in all index-out-of-bounds cases including seqs
Diffstat (limited to 'src')
-rw-r--r-- | src/boot.clj | 10 | ||||
-rw-r--r-- | src/jvm/clojure/lang/RT.java | 53 |
2 files changed, 58 insertions, 5 deletions
diff --git a/src/boot.clj b/src/boot.clj index 589bb177..7c3ac083 100644 --- a/src/boot.clj +++ b/src/boot.clj @@ -758,9 +758,11 @@ (defn nth "Returns the value at the index. get returns nil if index out of - bounds, nth throws an exception. nth also works for strings, Java - arrays and Lists, and, in O(n) time, for sequences." - [coll index] (. clojure.lang.RT (nth coll index))) + bounds, nth throws an exception unless not-found is supplied. nth + also works for strings, Java arrays, regex Matchers and Lists, and, + in O(n) time, for sequences." + ([coll index] (. clojure.lang.RT (nth coll index))) + ([coll index not-found] (. clojure.lang.RT (nth coll index not-found)))) ;;map stuff @@ -1992,7 +1994,7 @@ not-every? (comp not every?)) (= firstb :as) (pb ret (second bs) gvec) :else (if seen-rest? (throw (new Exception "Unsupported binding form, only :as can follow & parameter")) - (recur (pb ret firstb (list `nth gvec n)) + (recur (pb ret firstb (list `nth gvec n nil)) (inc n) (rest bs) seen-rest?)))) diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java index 6784e4aa..10ab0016 100644 --- a/src/jvm/clojure/lang/RT.java +++ b/src/jvm/clojure/lang/RT.java @@ -597,7 +597,58 @@ static public Object nth(Object coll, int n){ if(i == n) return seq.first(); } - return null; + throw new IndexOutOfBoundsException(); + } + else + throw new UnsupportedOperationException("nth not supported on this type: " + coll.getClass().getSimpleName()); +} + +static public Object nth(Object coll, int n, Object notFound){ + if(coll == null) + return notFound; + else if(coll instanceof IPersistentVector) + { + IPersistentVector v = (IPersistentVector) coll; + if(n < v.count()) + return v.nth(n); + return notFound; + } + else if(coll instanceof String) + { + String s = (String) coll; + if(n < s.length()) + return Character.valueOf(s.charAt(n)); + return notFound; + } + else if(coll.getClass().isArray()) + { + if(n < Array.getLength(coll)) + return Array.get(coll, n); + return notFound; + } + else if(coll instanceof List) + { + List list = (List) coll; + if(n < list.size()) + return list.get(n); + return notFound; + } + else if(coll instanceof Matcher) + { + Matcher m = (Matcher) coll; + if(n < m.groupCount()) + return m.group(n); + return notFound; + } + else if(coll instanceof Sequential) + { + ISeq seq = ((IPersistentCollection) coll).seq(); + for(int i = 0; i <= n && seq != null; ++i, seq = seq.rest()) + { + if(i == n) + return seq.first(); + } + return notFound; } else throw new UnsupportedOperationException("nth not supported on this type: " + coll.getClass().getSimpleName()); |