1
0
mirror of https://github.com/janet-lang/janet synced 2024-06-24 06:03:17 +00:00

Add take/drop.

This commit is contained in:
curist 2019-08-05 21:36:24 +08:00
parent ca5dce5d9f
commit 18da183ef7
2 changed files with 62 additions and 0 deletions

View File

@ -702,6 +702,20 @@
(def i (find-index pred ind))
(if (= i nil) nil (get ind i)))
(defn take
"Take first n elements in an indexed type. Returns new indexed instance."
[n xs]
(def [f empty] (case (type xs)
:array [array/slice @[]]
:buffer [buffer/slice @""]
:string [string/slice ""]
:tarray [tarray/slice @[]]
:tuple [tuple/slice (if (= :parens (tuple/type xs)) '() [])]
(error "should provide an indexed type")))
(def len (if (= :tarray (type xs)) (tarray/length xs) (length xs)))
(def end (if (pos? n) (min n len) 0))
(f xs 0 end))
(defn take-until
"Same as (take-while (complement pred) ind)."
[pred ind]
@ -716,6 +730,20 @@
[pred ind]
(take-until (complement pred) ind))
(defn drop
"Drop first n elements in an indexed type. Returns new indexed instance."
[n xs]
(def [f empty] (case (type xs)
:array [array/slice @[]]
:buffer [buffer/slice @""]
:string [string/slice ""]
:tarray [tarray/slice @[]]
:tuple [tuple/slice (if (= :parens (tuple/type xs)) '() [])]
(error "should provide an indexed type")))
(def len (if (= :tarray (type xs)) (tarray/length xs) (length xs)))
(def start (if (pos? n) (min n len) 0))
(f xs start -1))
(defn drop-until
"Same as (drop-while (complement pred) ind)."
[pred ind]

View File

@ -80,6 +80,40 @@
(assert-no-error "break 3" (for i 0 10 (if (> i 8) (break i))))
(assert-no-error "break 4" ((fn [i] (if (> i 8) (break i))) 100))
# take
(assert (deep= (take 0 []) []) "take 1")
(assert (deep= (take 10 []) []) "take 2")
(assert (deep= (take 0 [1 2 3 4 5]) []) "take 3")
(assert (deep= (take 10 [1 2 3]) [1 2 3]) "take 4")
(assert (deep= (take -1 [:a :b :c]) []) "take 5")
(assert-error :invalid-type (take 3 {}) "take 6")
# take-until
(assert (deep= (take-until pos? @[]) @[]) "take-until 1")
(assert (deep= (take-until pos? @[1 2 3]) @[]) "take-until 2")
(assert (deep= (take-until pos? @[-1 -2 -3]) @[-1 -2 -3]) "take-until 3")
(assert (deep= (take-until pos? @[-1 -2 3]) @[-1 -2]) "take-until 4")
(assert (deep= (take-until pos? @[-1 1 -2]) @[-1]) "take-until 5")
# take-while
(assert (deep= (take-while neg? @[]) @[]) "take-while 1")
(assert (deep= (take-while neg? @[1 2 3]) @[]) "take-while 2")
(assert (deep= (take-while neg? @[-1 -2 -3]) @[-1 -2 -3]) "take-while 3")
(assert (deep= (take-while neg? @[-1 -2 3]) @[-1 -2]) "take-while 4")
(assert (deep= (take-while neg? @[-1 1 -2]) @[-1]) "take-while 5")
# drop
(assert (deep= (drop 0 []) []) "drop 1")
(assert (deep= (drop 10 []) []) "drop 2")
(assert (deep= (drop 0 [1 2 3 4 5]) [1 2 3 4 5]) "drop 3")
(assert (deep= (drop 10 [1 2 3]) []) "drop 4")
(assert (deep= (drop -2 [:a :b :c]) [:a :b :c]) "drop 5")
(assert-error :invalid-type (drop 3 {}) "drop 6")
# drop-until
(assert (deep= (drop-until pos? @[]) @[]) "drop-until 1")