Merge pull request #641 from microamp/issue-638

Fix #638: Make nth return default value when out of bounds
This commit is contained in:
Morten Linderud 2014-09-03 14:28:01 +02:00
commit bc0ef3ea14
4 changed files with 30 additions and 15 deletions

View File

@ -532,11 +532,11 @@ Return True if x is None.
nth nth
--- ---
Usage: ``(nth coll n)`` Usage: ``(nth coll n &optional [default nil])``
Return the `nth` item in a collection, counting from 0. Unlike Return the `nth` item in a collection, counting from 0. Return the
``get``, ``nth`` works on both iterators and iterables. Raises ``IndexError`` default value, ``nil``, if out of bounds (unless specified otherwise).
if the `n` is outside the range of ``coll`` or ``ValueError`` if it's negative. Raise ``ValueError`` if ``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)))