Skip to content

Commit af07c09

Browse files
bsnyder788lpil
authored andcommitted
map_dict:fold
1 parent 1c16eee commit af07c09

File tree

5 files changed

+65
-2
lines changed

5 files changed

+65
-2
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## Unreleased
4+
5+
- The `map_dict` module gains a `fold` function.
6+
37
## v0.2.0 - 2019-05-11
48

59
- Library renamed to `gleam_stdlib`.

gen/src/map_dict.erl

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
-module(map_dict).
22
-compile(no_auto_import).
33

4-
-export([size/1, to_list/1, from_list/1, has_key/2, new/0, fetch/2, put/3, map_values/2, keys/1, values/1, filter/2, take/2, merge/2, delete/2, drop/2, update/3]).
4+
-export([size/1, to_list/1, from_list/1, has_key/2, new/0, fetch/2, put/3, map_values/2, keys/1, values/1, filter/2, take/2, merge/2, delete/2, drop/2, update/3, fold/3]).
55

66
size(A) ->
77
maps:size(A).
@@ -74,3 +74,13 @@ update(Dict, Key, F) ->
7474
{error, _} ->
7575
put(Dict, Key, F({error, not_found}))
7676
end.
77+
78+
fold(Dict, Acc, F) ->
79+
Kvs = to_list(Dict),
80+
case Kvs of
81+
[] ->
82+
Acc;
83+
84+
[{K, V} | _] ->
85+
fold(delete(Dict, K), F(K, V, Acc), F)
86+
end.

gen/test/map_dict_test.erl

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
-module(map_dict_test).
22
-compile(no_auto_import).
33

4-
-export([from_list_test/0, has_key_test/0, new_test/0, fetch_test/0, put_test/0, map_values_test/0, keys_test/0, values_test/0, take_test/0, drop_test/0, merge_test/0, delete_test/0, update_test/0]).
4+
-export([from_list_test/0, has_key_test/0, new_test/0, fetch_test/0, put_test/0, map_values_test/0, keys_test/0, values_test/0, take_test/0, drop_test/0, merge_test/0, delete_test/0, update_test/0, fold_test/0]).
55

66
from_list_test() ->
77
expect:equal(map_dict:size(map_dict:from_list([{4, 0}, {1, 0}])), 2).
@@ -115,3 +115,14 @@ update_test() ->
115115
{<<"b">>, 1},
116116
{<<"c">>, 2},
117117
{<<"z">>, 0}])).
118+
119+
fold_test() ->
120+
Dict = map_dict:from_list([{<<"a">>, 0},
121+
{<<"b">>, 1},
122+
{<<"c">>, 2},
123+
{<<"d">>, 3}]),
124+
Add = fun(_, V, Acc) -> V + Acc end,
125+
expect:equal(map_dict:fold(Dict, 0, Add), 6),
126+
Concat = fun(K, _, Acc) -> str:append(Acc, K) end,
127+
expect:equal(map_dict:fold(Dict, <<"">>, Concat), <<"abcd">>),
128+
expect:equal(map_dict:fold(map_dict:from_list([]), 0, Add), 0).

src/map_dict.gleam

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,11 @@ pub fn update(dict, key, f) {
8686
| Error(_) -> put(dict, key, f(Error(NotFound)))
8787
}
8888
}
89+
90+
pub fn fold(dict, acc, f) {
91+
let kvs = to_list(dict)
92+
case kvs {
93+
| [] -> acc
94+
| [{k, v} | _] -> fold(delete(dict, k), f(k, v, acc), f)
95+
}
96+
}

test/map_dict_test.gleam

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import expect
22
import map_dict
3+
import str
34

45
pub fn from_list_test() {
56
[
@@ -201,3 +202,32 @@ pub fn update_test() {
201202
|> map_dict:update(_, "z", inc_or_zero)
202203
|> expect:equal(_, map_dict:from_list([{"a", 0}, {"b", 1}, {"c", 2}, {"z", 0}]))
203204
}
205+
206+
pub fn fold_test() {
207+
let dict = map_dict:from_list([
208+
{"a", 0},
209+
{"b", 1},
210+
{"c", 2},
211+
{"d", 3},
212+
])
213+
214+
let add = fn(_, v, acc) {
215+
v + acc
216+
}
217+
218+
dict
219+
|> map_dict:fold(_, 0, add)
220+
|> expect:equal(_, 6)
221+
222+
let concat = fn(k, _, acc) {
223+
str:append(acc, k)
224+
}
225+
226+
dict
227+
|> map_dict:fold(_, "", concat)
228+
|> expect:equal(_, "abcd")
229+
230+
map_dict:from_list([])
231+
|> map_dict:fold(_, 0, add)
232+
|> expect:equal(_, 0)
233+
}

0 commit comments

Comments
 (0)