1
0
mirror of https://github.com/janet-lang/janet synced 2024-11-24 17:27:18 +00:00

Add array/clear.

Also improve map, find-index, and find to work on data structures
which do not defined length.
This commit is contained in:
Calvin Rose 2020-12-18 11:03:57 -06:00
parent a55354357c
commit 25ded775ad
3 changed files with 86 additions and 25 deletions

View File

@ -898,21 +898,52 @@
[f & inds] [f & inds]
(def ninds (length inds)) (def ninds (length inds))
(if (= 0 ninds) (error "expected at least 1 indexed collection")) (if (= 0 ninds) (error "expected at least 1 indexed collection"))
(var limit (length (in inds 0))) (def res @[])
(forv i 0 ninds
(def l (length (in inds i)))
(if (< l limit) (set limit l)))
(def [i1 i2 i3 i4] inds) (def [i1 i2 i3 i4] inds)
(def res (array/new limit))
(case ninds (case ninds
1 (forv i 0 limit (set (res i) (f (in i1 i)))) 1 (each x i1 (array/push res (f x)))
2 (forv i 0 limit (set (res i) (f (in i1 i) (in i2 i)))) 2 (do
3 (forv i 0 limit (set (res i) (f (in i1 i) (in i2 i) (in i3 i)))) (var k1 nil)
4 (forv i 0 limit (set (res i) (f (in i1 i) (in i2 i) (in i3 i) (in i4 i)))) (var k2 nil)
(forv i 0 limit (while true
(def args (array/new ninds)) (if (= nil (set k1 (next i1 k1))) (break))
(forv j 0 ninds (set (args j) (in (in inds j) i))) (if (= nil (set k2 (next i2 k2))) (break))
(set (res i) (f ;args)))) (array/push res (f (in i1 k1) (in i2 k2)))))
3 (do
(var k1 nil)
(var k2 nil)
(var k3 nil)
(while true
(if (= nil (set k1 (next i1 k1))) (break))
(if (= nil (set k2 (next i2 k2))) (break))
(if (= nil (set k3 (next i2 k3))) (break))
(array/push res (f (in i1 k1) (in i2 k2) (in i3 k3)))))
4 (do
(var k1 nil)
(var k2 nil)
(var k3 nil)
(var k4 nil)
(while true
(if (= nil (set k1 (next i1 k1))) (break))
(if (= nil (set k2 (next i2 k2))) (break))
(if (= nil (set k3 (next i2 k3))) (break))
(if (= nil (set k4 (next i2 k4))) (break))
(array/push res (f (in i1 k1) (in i2 k2) (in i3 k3) (in i4 k4)))))
(do
(def iterkeys (array/new-filled ninds))
(var done false)
(def call-buffer @[])
(while true
(forv i 0 ninds
(let [old-key (in iterkeys i)
ii (in inds i)
new-key (next ii old-key)]
(if (= nil new-key)
(do (set done true) (break))
(do (set (iterkeys i) new-key) (array/push call-buffer (in ii new-key))))))
(if done (break))
(array/push res (f ;call-buffer))
(array/clear call-buffer))))
res) res)
(defn mapcat (defn mapcat
@ -983,21 +1014,31 @@
(defn find-index (defn find-index
`Find the index of indexed type for which pred is true. Returns nil if not found.` `Find the index of indexed type for which pred is true. Returns nil if not found.`
[pred ind] [pred ind]
(def len (length ind)) (var k nil)
(var i 0) (var ret nil)
(var going true) (while true
(while (if (< i len) going) (set k (next ind k))
(def item (in ind i)) (if (= k nil) (break))
(if (pred item) (set going false) (++ i))) (def item (in ind k))
(if going nil i)) (when (pred item)
(set ret k)
(break)))
ret)
(defn find (defn find
`Find the first value in an indexed collection that satisfies a predicate. Returns `Find the first value in an indexed collection that satisfies a predicate. Returns
nil if not found. Note there is no way to differentiate a nil from the indexed collection dflt if not found.`
and a not found. Consider find-index if this is an issue.` [pred ind &opt dflt]
[pred ind] (var k nil)
(def i (find-index pred ind)) (var ret dflt)
(if (= i nil) nil (in ind i))) (while true
(set k (next ind k))
(if (= k nil) (break))
(def item (in ind k))
(when (pred item)
(set ret item)
(break)))
ret)
(defn index-of (defn index-of
`Find the first key associated with a value x in a data structure, acting like a reverse lookup. `Find the first key associated with a value x in a data structure, acting like a reverse lookup.

View File

@ -290,6 +290,13 @@ static Janet cfun_array_trim(int32_t argc, Janet *argv) {
return argv[0]; return argv[0];
} }
static Janet cfun_array_clear(int32_t argc, Janet *argv) {
janet_fixarity(argc, 1);
JanetArray *array = janet_getarray(argv, 0);
array->count = 0;
return argv[0];
}
static const JanetReg array_cfuns[] = { static const JanetReg array_cfuns[] = {
{ {
"array/new", cfun_array_new, "array/new", cfun_array_new,
@ -370,6 +377,12 @@ static const JanetReg array_cfuns[] = {
JDOC("(array/trim arr)\n\n" JDOC("(array/trim arr)\n\n"
"Set the backing capacity of an array to its current length. Returns the modified array.") "Set the backing capacity of an array to its current length. Returns the modified array.")
}, },
{
"array/clear", cfun_array_clear,
JDOC("(array/clear arr)\n\n"
"Empties an array, setting it's count to 0 but does not free the backing capacity. "
"Returns the modified array.")
},
{NULL, NULL, NULL} {NULL, NULL, NULL}
}; };

View File

@ -281,4 +281,11 @@
(assert (not (even? -10.1)) "even? 8") (assert (not (even? -10.1)) "even? 8")
(assert (not (even? -10.6)) "even? 9") (assert (not (even? -10.6)) "even? 9")
# Map arities
(assert (deep= (map inc [1 2 3]) @[2 3 4]))
(assert (deep= (map + [1 2 3] [10 20 30]) @[11 22 33]))
(assert (deep= (map + [1 2 3] [10 20 30] [100 200 300]) @[111 222 333]))
(assert (deep= (map + [1 2 3] [10 20 30] [100 200 300] [1000 2000 3000]) @[1111 2222 3333]))
(assert (deep= (map + [1 2 3] [10 20 30] [100 200 300] [1000 2000 3000] [10000 20000 30000]) @[11111 22222 33333]))
(end-suite) (end-suite)