feat: add Array.map-reduce (#1201)

* feat: add Array.map-reduce

* test: add map-reduce to memory tests
This commit is contained in:
Veit Heller 2021-04-19 16:45:15 +02:00 committed by GitHub
parent 35465b9ffa
commit 00146c70b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 3 deletions

View File

@ -414,7 +414,32 @@ It will create a copy. If you want to avoid that, consider using [`endo-filter`]
(let-do [darr (allocate (StaticArray.length sarr))]
(for [i 0 (StaticArray.length sarr)]
(aset-uninitialized! &darr i @(StaticArray.unsafe-nth sarr i)))
darr)))
darr))
(doc map-reduce "reduces an array `a` by invoking the function `f` on each
element, while keeping an accumulator and a list.
Returns a `Pair` where the first element is the mapped array and the second one
is the final accumulator.
The function `f` receives two arguments: the first one is the element, and the
second one is the accumulator. `f` must return `(Pair result accumulator)`.
Example:
```
(map-reduce &(fn [acc x] (Pair.init (+ @x @acc) (* @x 2))) 0 &[1 2 3])
; => (Pair 6 [2 4 6])
```")
(defn map-reduce [f acc a]
(reduce
&(fn [a el]
(let [l (Pair.b &a)
acc (Pair.a &a)
p (~f acc el)]
(Pair.init @(Pair.a &p) (Array.push-back @l @(Pair.b &p)))))
(Pair.init acc [])
a))
)
(defmacro doall [f xs]
`(for [i 0 (Array.length &%xs)]

View File

@ -330,5 +330,9 @@
(assert-ref-equal test
[1 2 3]
(from-static $[1 2 3])
"from-static works"))
"from-static works")
(assert-ref-equal test
(Pair.init 6 [2 4 6])
(map-reduce &(fn [acc x] (Pair.init (+ @x @acc) (* @x 2))) 0 &[1 2 3])
"map-reduce works")
)

View File

@ -329,6 +329,10 @@
ys (Array.copy-map &str-ref &xs)]
(assert (= &[@"1" @"2" @"3" @"4"] &ys))))
(defn array-map-reduce []
(let [r (map-reduce &(fn [acc x] (Pair.init (append acc x) (append "-" x))) @"" &[@"1" @"2" @"3"])]
(assert (= &r &(Pair.init @"123" [@"-1" @"-2" @"-3"])))))
(defn string-append-leak-test []
(let [a "abcdef"
b "ghijklmnopqrstuvwxyz"]
@ -487,6 +491,7 @@
(assert-no-leak test array-replicate "array-replicate does not leak")
(assert-no-leak test array-copy-map-1 "array-copy-map-1 does not leak")
(assert-no-leak test array-copy-map-2 "array-copy-map-2 does not leak")
(assert-no-leak test array-map-reduce "array-map-reduce does not leak")
(assert-no-leak test string-append-leak-test "String.append does not leak")
(assert-no-leak test lambda-1 "lambda-1 does not leak")
(assert-no-leak test lambda-2 "lambda-2 does not leak")