diff options
author | Sebastian Porto <s@porto5.com> | 2021-04-08 21:48:12 +1000 |
---|---|---|
committer | Louis Pilfold <louis@lpil.uk> | 2021-04-09 10:39:19 +0100 |
commit | 895bb26dd125d946653c53897e73bdf88ae5555d (patch) | |
tree | 649b6f423fc4c8bd419230ee593421a423e940d8 | |
parent | 8d83506941b16722aed6eab102565bfd163ba053 (diff) | |
download | gleam_stdlib-895bb26dd125d946653c53897e73bdf88ae5555d.tar.gz gleam_stdlib-895bb26dd125d946653c53897e73bdf88ae5555d.zip |
Add list.map_reduce
-rw-r--r-- | src/gleam/list.gleam | 30 | ||||
-rw-r--r-- | test/gleam/list_test.gleam | 6 |
2 files changed, 36 insertions, 0 deletions
diff --git a/src/gleam/list.gleam b/src/gleam/list.gleam index 7df9862..6d9c709 100644 --- a/src/gleam/list.gleam +++ b/src/gleam/list.gleam @@ -246,6 +246,36 @@ pub fn map(list: List(a), with fun: fn(a) -> b) -> List(b) { do_map(list, fun, []) } +/// Similar to map but also lets you pass around an accumulated value. +/// +/// ## Examples +/// +/// ``` +/// > map_reduce( +/// over: [1, 2, 3], +/// from: 100, +/// with: fn(memo, i) { tuple(memo + i, i * 2) } +/// ) +/// tuple(106, [2, 4, 6]) +/// ``` +/// +pub fn map_reduce( + over list: List(a), + from memo: memo, + with fun: fn(memo, a) -> tuple(memo, b), +) -> tuple(memo, List(b)) { + fold( + over: list, + from: tuple(memo, []), + with: fn(item, acc) { + let tuple(current_memo, items) = acc + let tuple(next_memo, next_item) = fun(current_memo, item) + tuple(next_memo, [next_item, ..items]) + }, + ) + |> pair.map_second(reverse) +} + fn do_index_map( list: List(a), fun: fn(Int, a) -> b, diff --git a/test/gleam/list_test.gleam b/test/gleam/list_test.gleam index b561d33..fa87952 100644 --- a/test/gleam/list_test.gleam +++ b/test/gleam/list_test.gleam @@ -99,6 +99,12 @@ pub fn map_test() { |> should.equal([0, 8, 10, 14, 6]) } +pub fn map_reduce_test() { + [1, 2, 3, 4] + |> list.map_reduce(from: 0, with: fn(acc, i) { tuple(acc + i, i * 2) }) + |> should.equal(tuple(10, [2, 4, 6, 8])) +} + pub fn try_map_test() { let fun = fn(x) { case x == 6 || x == 5 || x == 4 { |