Make nth return default value when out of bounds

This commit is contained in:
han semaj 2014-08-23 23:35:31 +12:00
parent 7e5befa615
commit ecc664337d
4 changed files with 29 additions and 14 deletions

View File

@ -534,9 +534,9 @@ nth
Usage: ``(nth coll n)`` Usage: ``(nth coll n)``
Return the `nth` item in a collection, counting from 0. Unlike Return the `nth` item in a collection, counting from 0. Return ``nil``
``get``, ``nth`` works on both iterators and iterables. Raises ``IndexError`` if out of bounds (unless specified otherwise). Raise ``ValueError`` if
if the `n` is outside the range of ``coll`` or ``ValueError`` if it's negative. ``n`` is negative.
.. code-block:: hy .. code-block:: hy
@ -546,14 +546,21 @@ if the `n` is outside the range of ``coll`` or ``ValueError`` if it's negative.
=> (nth [1 2 4 7] 3) => (nth [1 2 4 7] 3)
7 7
=> (nth [1 2 4 7] 5) => (nil? (nth [1 2 4 7] 5))
Traceback (most recent call last): True
...
IndexError: 5 => (nth [1 2 4 7] 5 "default")
'default'
=> (nth (take 3 (drop 2 [1 2 3 4 5 6])) 2)) => (nth (take 3 (drop 2 [1 2 3 4 5 6])) 2))
5 5
=> (nth [1 2 4 7] -1)
Traceback (most recent call last):
...
ValueError: Indices for islice() must be None or an integer: 0 <= x <= sys.maxsize.
.. _numeric?-fn: .. _numeric?-fn:
numeric? numeric?

View File

@ -270,11 +270,10 @@
(import numbers) (import numbers)
(instance? numbers.Number x)) (instance? numbers.Number x))
(defn nth [coll index] (defn nth [coll n &optional [default nil]]
"Return nth item in collection or sequence, counting from 0" "Return nth item in collection or sequence, counting from 0.
(try Return nil if out of bounds unless specified otherwise."
(next (drop index coll)) (next (drop n coll) default))
(catch [e StopIteration] (raise (IndexError index)))))
(defn odd? [n] (defn odd? [n]
"Return true if n is an odd number" "Return true if n is an odd number"

View File

@ -30,6 +30,9 @@
(defn assert-equal [x y] (defn assert-equal [x y]
(assert (= x y))) (assert (= x y)))
(defn assert-nil [x]
(assert (is x nil)))
(defn test-coll? [] (defn test-coll? []
"NATIVE: testing coll?" "NATIVE: testing coll?"
(assert-true (coll? [1 2 3])) (assert-true (coll? [1 2 3]))
@ -390,13 +393,17 @@
"NATIVE: testing the nth function" "NATIVE: testing the nth function"
(assert-equal 2 (nth [1 2 4 7] 1)) (assert-equal 2 (nth [1 2 4 7] 1))
(assert-equal 7 (nth [1 2 4 7] 3)) (assert-equal 7 (nth [1 2 4 7] 3))
(try (do (nth [1 2 4 7] 5) (assert False)) (assert-nil (nth [1 2 4 7] 5))
(catch [e [IndexError]] nil)) (assert-equal (nth [1 2 4 7] 5 "some default value")
"some default value") ; with default specified
(try (do (nth [1 2 4 7] -1) (assert False)) (try (do (nth [1 2 4 7] -1) (assert False))
(catch [e [ValueError]] nil)) (catch [e [ValueError]] nil))
;; now for iterators ;; now for iterators
(assert-equal 2 (nth (iter [1 2 4 7]) 1)) (assert-equal 2 (nth (iter [1 2 4 7]) 1))
(assert-equal 7 (nth (iter [1 2 4 7]) 3)) (assert-equal 7 (nth (iter [1 2 4 7]) 3))
(assert-nil (nth (iter [1 2 4 7]) 5))
(assert-equal (nth (iter [1 2 4 7]) 5 "some default value")
"some default value") ; with default specified
(try (do (nth (iter [1 2 4 7]) -1) (assert False)) (try (do (nth (iter [1 2 4 7]) -1) (assert False))
(catch [e [ValueError]] nil)) (catch [e [ValueError]] nil))
(assert-equal 5 (nth (take 3 (drop 2 [1 2 3 4 5 6])) 2))) (assert-equal 5 (nth (take 3 (drop 2 [1 2 3 4 5 6])) 2)))

View File

@ -495,9 +495,11 @@
(setv output (list (gen))) (setv output (list (gen)))
(assert (= [1] output))) (assert (= [1] output)))
(defn test-first [] (defn test-first []
"NATIVE: test firsty things" "NATIVE: test firsty things"
(assert (= (first [1 2 3 4 5]) 1)) (assert (= (first [1 2 3 4 5]) 1))
(assert (is (first []) nil))
(assert (= (car [1 2 3 4 5]) 1))) (assert (= (car [1 2 3 4 5]) 1)))