diff options
author | Matthew McMillan <matt@matthewmcmillan.me> | 2021-08-30 00:24:24 -0400 |
---|---|---|
committer | Louis Pilfold <louis@lpil.uk> | 2021-09-01 20:10:33 +0100 |
commit | 9f064a8497872b976c9ed089a21b47a3d92295ab (patch) | |
tree | 110373b761f41b00e05eb23173952b98248c65c1 | |
parent | 0dc4a0aed4cbe8b9a2b3a575f112bbd30f0de39d (diff) | |
download | gleam_stdlib-9f064a8497872b976c9ed089a21b47a3d92295ab.tar.gz gleam_stdlib-9f064a8497872b976c9ed089a21b47a3d92295ab.zip |
First attempt at map implementation
-rwxr-xr-x[-rw-r--r--] | bin/run-tests.js | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | bin/test.sh | 0 | ||||
-rw-r--r-- | src/gleam/map.gleam | 707 | ||||
-rw-r--r-- | src/gleam_stdlib.js | 64 | ||||
-rw-r--r-- | test/gleam/map_test.gleam | 280 |
5 files changed, 622 insertions, 429 deletions
diff --git a/bin/run-tests.js b/bin/run-tests.js index 3eaba7c..3eaba7c 100644..100755 --- a/bin/run-tests.js +++ b/bin/run-tests.js diff --git a/bin/test.sh b/bin/test.sh index 777c50b..777c50b 100644..100755 --- a/bin/test.sh +++ b/bin/test.sh diff --git a/src/gleam/map.gleam b/src/gleam/map.gleam index 7fd363f..ebb199a 100644 --- a/src/gleam/map.gleam +++ b/src/gleam/map.gleam @@ -1,329 +1,460 @@ +import gleam/result +import gleam/option.{Option} +import gleam/list + +/// A dictionary of keys and values. +/// +/// Any type can be used for the keys and values of a map, but all the keys +/// must be of the same type and all the values must be of the same type. +/// +/// Each key can only be present in a map once. +/// +/// Maps are not ordered in any way, and any unintentional ordering is not to +/// be relied upon in your code as it may change in future versions of Erlang +/// or Gleam. +/// +/// See [the Erlang map module](https://erlang.org/doc/man/maps.html) for more +/// information. +/// +pub external type Map(key, value) + +/// Determines the number of key-value pairs in the map. +/// This function runs in constant time and does not need to iterate the map. +/// +/// ## Examples +/// +/// > new() |> size() +/// 0 +/// +/// > new() |> insert("key", "value") |> size() +/// 1 +/// +/// +pub fn size(map: Map(k, v)) -> Int { + do_size(map) +} + if erlang { - import gleam/result - import gleam/option.{Option} - import gleam/list - - /// A dictionary of keys and values. - /// - /// Any type can be used for the keys and values of a map, but all the keys - /// must be of the same type and all the values must be of the same type. - /// - /// Each key can only be present in a map once. - /// - /// Maps are not ordered in any way, and any unintentional ordering is not to - /// be relied upon in your code as it may change in future versions of Erlang - /// or Gleam. - /// - /// See [the Erlang map module](https://erlang.org/doc/man/maps.html) for more - /// information. - /// - pub external type Map(key, value) - - /// Determines the number of key-value pairs in the map. - /// This function runs in constant time and does not need to iterate the map. - /// - /// ## Examples - /// - /// > new() |> size() - /// 0 - /// - /// > new() |> insert("key", "value") |> size() - /// 1 - /// - /// - pub external fn size(Map(k, v)) -> Int = + external fn do_size(Map(k, v)) -> Int = "maps" "size" +} + +if javascript { + external fn do_size(Map(k, v)) -> Int = + "../gleam_stdlib.js" "map_size" +} + +/// Converts the map to a list of 2-element tuples `#(key, value)`, one for +/// each key-value pair in the map. +/// +/// The tuples in the list have no specific order. +/// +/// ## Examples +/// +/// > new() |> to_list() +/// [] +/// +/// > new() |> insert("key", 0) |> to_list() +/// [#("key", 0)] +/// +pub fn to_list(map: Map(key, value)) -> List(#(key, value)) { + do_to_list(map) +} - /// Converts the map to a list of 2-element tuples `#(key, value)`, one for - /// each key-value pair in the map. - /// - /// The tuples in the list have no specific order. - /// - /// ## Examples - /// - /// > new() |> to_list() - /// [] - /// - /// > new() |> insert("key", 0) |> to_list() - /// [#("key", 0)] - /// - pub external fn to_list(Map(key, value)) -> List(#(key, value)) = +if erlang { + external fn do_to_list(Map(key, value)) -> List(#(key, value)) = "maps" "to_list" +} + +if javascript { + external fn do_to_list(Map(key, value)) -> List(#(key, value)) = + "../gleam_stdlib.js" "map_to_list" +} + +/// Converts a list of 2-element tuples `#(key, value)` to a map. +/// +/// If two tuples have the same key the last one in the list will be the one +/// that is present in the map. +/// +pub fn from_list(list: List(#(key, value))) -> Map(key, value) { + do_from_list(list) +} - /// Converts a list of 2-element tuples `#(key, value)` to a map. - /// - /// If two tuples have the same key the last one in the list will be the one - /// that is present in the map. - /// - pub external fn from_list(List(#(key, value))) -> Map(key, value) = +if erlang { + external fn do_from_list(List(#(key, value))) -> Map(key, value) = "maps" "from_list" +} + +if javascript { + external fn do_from_list(List(#(key, value))) -> Map(key, value) = + "../gleam_stdlib.js" "map_to_list" +} + +/// Determines whether or not a value present in the map for a given key. +/// +/// ## Examples +/// +/// > new() |> insert("a", 0) |> has_key("a") +/// True +/// +/// > new() |> insert("a", 0) |> has_key("b") +/// False +/// +pub fn has_key(map: Map(k, v), key: k) -> Bool { + do_has_key(key, map) +} - external fn is_key(key, Map(key, v)) -> Bool = +if erlang { + external fn do_has_key(key, Map(key, v)) -> Bool = "maps" "is_key" +} - /// Determines whether or not a value present in the map for a given key. - /// - /// ## Examples - /// - /// > new() |> insert("a", 0) |> has_key("a") - /// True - /// - /// > new() |> insert("a", 0) |> has_key("b") - /// False - /// - pub fn has_key(map: Map(k, v), key: k) -> Bool { - is_key(key, map) - } +if javascript { + external fn do_has_key(k, Map(k, v)) -> Bool = + "../gleam_stdlib.js" "map_has_key" +} + +/// Creates a fresh map that contains no values. +/// +pub fn new() -> Map(key, value) { + do_new() +} - /// Creates a fresh map that contains no values. - /// - pub external fn new() -> Map(key, value) = +if erlang { + external fn do_new() -> Map(key, value) = "maps" "new" +} + +if javascript { + external fn do_new() -> Map(key, value) = + "../gleam_stdlib.js" "new_map" +} + +/// Fetches a value from a map for a given key. +/// +/// The map may not have a value for the key, so the value is wrapped in a +/// Result. +/// +/// ## Examples +/// +/// > new() |> insert("a", 0) |> get("a") +/// Ok(0) +/// +/// > new() |> insert("a", 0) |> get("b") +/// Error(Nil) +/// +pub fn get(from: Map(key, value), get: key) -> Result(value, Nil) { + do_get(from, get); +} - /// Fetches a value from a map for a given key. - /// - /// The map may not have a value for the key, so the value is wrapped in a - /// Result. - /// - /// ## Examples - /// - /// > new() |> insert("a", 0) |> get("a") - /// Ok(0) - /// - /// > new() |> insert("a", 0) |> get("b") - /// Error(Nil) - /// - pub external fn get(from: Map(key, value), get: key) -> Result(value, Nil) = +if erlang { + external fn do_get(Map(key, value), key) -> Result(value, Nil) = "gleam_stdlib" "map_get" +} + +if javascript { + external fn do_get(Map(key, value), key) -> Result(value, Nil) = + "../gleam_stdlib.js" "map_get" +} + +/// Inserts a value into the map with the given key. +/// +/// If the map already has a value for the given key then the value is +/// replaced with the new value. +/// +/// ## Examples +/// +/// > new() |> insert("a", 0) |> to_list +/// [#("a", 0)] +/// +/// > new() |> insert("a", 0) |> insert("a", 5) |> to_list +/// [#("a", 5)] +/// +pub fn insert(into map: Map(k, v), for key: k, insert value: v) -> Map(k, v) { + do_insert(key, value, map) +} - external fn erl_insert(key, value, Map(key, value)) -> Map(key, value) = +if erlang { + external fn do_insert(key, value, Map(key, value)) -> Map(key, value) = "maps" "put" +} - /// Inserts a value into the map with the given key. - /// - /// If the map already has a value for the given key then the value is - /// replaced with the new value. - /// - /// ## Examples - /// - /// > new() |> insert("a", 0) |> to_list - /// [#("a", 0)] - /// - /// > new() |> insert("a", 0) |> insert("a", 5) |> to_list - /// [#("a", 5)] - /// - pub fn insert(into map: Map(k, v), for key: k, insert value: v) -> Map(k, v) { - erl_insert(key, value, map) - } +if javascript { + external fn do_insert(key, value, Map(key, value)) -> Map(key, value) = + "../gleam_stdlib.js" "map_insert" +} + +/// Updates all values in a given map by calling a given function on each key +/// and value. +/// +/// ## Examples +/// +/// > [#(3, 3), #(2, 4)] +/// > |> from_list +/// > |> map_values(fn(key, value) { key * value }) +/// [#(3, 9), #(2, 8)] +/// +/// +pub fn map_values(in map: Map(k, v), with fun: fn(k, v) -> w) -> Map(k, w) { + do_map_values(fun, map) +} - external fn erl_map_values(fn(key, a) -> b, Map(key, value)) -> Map(key, b) = +if erlang { + external fn do_map_values(fn(key, a) -> b, Map(key, value)) -> Map(key, b) = "maps" "map" +} - /// Updates all values in a given map by calling a given function on each key - /// and value. - /// - /// ## Examples - /// - /// > [#(3, 3), #(2, 4)] - /// > |> from_list - /// > |> map_values(fn(key, value) { key * value }) - /// [#(3, 9), #(2, 8)] - /// - /// - pub fn map_values(in map: Map(k, v), with fun: fn(k, v) -> w) -> Map(k, w) { - erl_map_values(fun, map) - } +if javascript { + external fn do_map_values(fn(key, a) -> b, Map(key, value)) -> Map(key, b) = + "../gleam_stdlib.js" "map_map_values" +} + +/// Gets a list of all keys in a given map. +/// +/// Maps are not ordered so the keys are not returned in any specific order. Do +/// not write code that relies on the order keys are returned by this function +/// as it may change in later versions of Gleam or Erlang. +/// +/// ## Examples +/// +/// > keys([#("a", 0), #("b", 1)]) +/// ["a", "b"] +/// +pub fn keys(map: Map(keys, v)) -> List(keys) { + do_keys(map) +} - /// Gets a list of all keys in a given map. - /// - /// Maps are not ordered so the keys are not returned in any specific order. Do - /// not write code that relies on the order keys are returned by this function - /// as it may change in later versions of Gleam or Erlang. - /// - /// ## Examples - /// - /// > keys([#("a", 0), #("b", 1)]) - /// ["a", "b"] - /// - pub external fn keys(Map(keys, v)) -> List(keys) = +if erlang { + external fn do_keys(Map(keys, v)) -> List(keys) = "maps" "keys" +} + +if javascript { + external fn do_keys(Map(keys, v)) -> List(keys) = + "../gleam_stdlib.js" "map_keys" +} + +/// Gets a list of all values in a given map. +/// +/// Maps are not ordered so the values are not returned in any specific order. Do +/// not write code that relies on the order values are returned by this function +/// as it may change in later versions of Gleam or Erlang. +/// +/// ## Examples +/// +/// > keys(from_list([#("a", 0), #("b", 1)])) +/// [0, 1] +/// +pub fn values(map: Map(k, values)) -> List(values) { + do_values(map) +} - /// Gets a list of all values in a given map. - /// - /// Maps are not ordered so the values are not returned in any specific order. Do - /// not write code that relies on the order values are returned by this function - /// as it may change in later versions of Gleam or Erlang. - /// - /// ## Examples - /// - /// > keys(from_list([#("a", 0), #("b", 1)])) - /// [0, 1] - /// - pub external fn values(Map(k, values)) -> List(values) = +if erlang { + external fn do_values(Map(k, values)) -> List(values) = "maps" "values" +} + +if javascript { + external fn do_values(Map(k, values)) -> List(values) = + "../gleam_stdlib.js" "map_values" +} + +/// Creates a new map from a given map, minus any entries that a given function +/// returns False for. +/// +/// ## Examples +/// +/// > from_list([#("a", 0), #("b", 1)]) +/// > |> filter(fn(key, value) { value != 0 }) +/// from_list([#("b", 1)]) +/// +/// > from_list([#("a", 0), #("b", 1)]) +/// > |> filter(fn(key, value) { True }) +/// from_list([#("a", 0), #("b", 1)]) +/// +pub fn filter(in map: Map(k, v), for property: fn(k, v) -> Bool) -> Map(k, v) { + do_filter(property, map) +} - external fn erl_filter( +if erlang { + external fn do_filter( fn(key, value) -> Bool, Map(key, value), ) -> Map(key, value) = "maps" "filter" +} - /// Creates a new map from a given map, minus any entries that a given function - /// returns False for. - /// - /// ## Examples - /// - /// > from_list([#("a", 0), #("b", 1)]) - /// > |> filter(fn(key, value) { value != 0 }) - /// from_list([#("b", 1)]) - /// - /// > from_list([#("a", 0), #("b", 1)]) - /// > |> filter(fn(key, value) { True }) - /// from_list([#("a", 0), #("b", 1)]) - /// - pub fn filter(in map: Map(k, v), for property: fn(k, v) -> Bool) -> Map(k, v) { - erl_filter(property, map) - } +if javascript { + external fn do_filter( + fn(key, value) -> Bool, + Map(key, value), + ) -> Map(key, value) = + "../gleam_stdlib.js" "map_filter" +} - external fn erl_take(List(k), Map(k, v)) -> Map(k, v) = - "maps" "with" - - /// Creates a new map from a given map, only including any entries for which the - /// keys are in a given list. - /// - /// ## Examples - /// - /// > from_list([#("a", 0), #("b", 1)]) - /// > |> take(["b"]) - /// from_list([#("b", 1)]) - /// - /// > from_list([#("a", 0), #("b", 1)]) - /// > |> take(["a", "b", "c"]) - /// from_list([#("a", 0), #("b", 1)]) - /// - pub fn take(from map: Map(k, v), keeping desired_keys: List(k)) -> Map(k, v) { - erl_take(desired_keys, map) - } +/// Creates a new map from a given map, only including any entries for which the +/// keys are in a given list. +/// +/// ## Examples +/// +/// > from_list([#("a", 0), #("b", 1)]) +/// > |> take(["b"]) +/// from_list([#("b", 1)]) +/// +/// > from_list([#("a", 0), #("b", 1)]) +/// > |> take(["a", "b", "c"]) +/// from_list([#("a", 0), #("b", 1)]) +/// +pub fn take(from map: Map(k, v), keeping desired_keys: List(k)) -> Map(k, v) { + do_take(desired_keys, map) +} - /// Creates a new map from a pair of given maps by combining their entries. - /// - /// If there are entries with the same keys in both maps the entry from the - /// second map takes precedence. - /// - /// ## Examples - /// - /// > let a = from_list([#("a", 0), #("b", 1)]) - /// > let b = from_list([#("b", 2), #("c", 3)]) - /// > merge(a, b) - /// from_list([#("a", 0), #("b", 2), #("c", 3)]) - /// - pub external fn merge(into: Map(k, v), merge: Map(k, v)) -> Map(k, v) = +if erlang { + external fn do_take(List(k), Map(k, v)) -> Map(k, v) = + "maps" "with" +} + +if javascript { + external fn do_take(List(k), Map(k, v)) -> Map(k, v) = + "../gleam_stdlib.js" "map_take" +} + +/// Creates a new map from a pair of given maps by combining their entries. +/// +/// If there are entries with the same keys in both maps the entry from the +/// second map takes precedence. +/// +/// ## Examples +/// +/// > let a = from_list([#("a", 0), #("b", 1)]) +/// > let b = from_list([#("b", 2), #("c", 3)]) +/// > merge(a, b) +/// from_list([#("a", 0), #("b", 2), #("c", 3)]) +/// +pub fn merge(into: Map(k, v), merge: Map(k, v)) -> Map(k, v) { + do_merge(into, merge) +} + +if erlang { + external fn do_merge(into: Map(k, v), merge: Map(k, v)) -> Map(k, v) = "maps" "merge" +} - external fn erl_delete(k, Map(k, v)) -> Map(k, v) = +if javascript { + external fn do_merge(into: Map(k, v), merge: Map(k, v)) -> Map(k, v) = + "../gleam_stdlib.js" "map_merge" +} + +/// Creates a new map from a given map with all the same entries except for the +/// one with a given key, if it exists. +/// +/// ## Examples +/// +/// > delete([#("a", 0), #("b", 1)], "a") +/// from_list([#("b", 1)]) +/// +/// > delete([#("a", 0), #("b", 1)], "c") +/// from_list([#("a", 0), #("b", 1)]) +/// +pub fn delete(from map: Map(k, v), delete key: k) -> Map(k, v) { + do_delete(key, map) +} + +if erlang { + external fn do_delete(k, Map(k, v)) -> Map(k, v) = "maps" "remove" +} - /// Creates a new map from a given map with all the same entries except for the - /// one with a given key, if it exists. - /// - /// ## Examples - /// - /// > delete([#("a", 0), #("b", 1)], "a") - /// from_list([#("b", 1)]) - /// - /// > delete([#("a", 0), #("b", 1)], "c") - /// from_list([#("a", 0), #("b", 1)]) - /// - pub fn delete(from map: Map(k, v), delete key: k) -> Map(k, v) { - erl_delete(key, map) - } +if javascript { + external fn do_delete(k, Map(k, v)) -> Map(k, v) = + "../gleam_stdlib.js" "map_remove" +} - /// Creates a new map from a given map with all the same entries except any with - /// keys found in a given list. - /// - /// ## Examples - /// - /// > drop([#("a", 0), #("b", 1)], ["a"]) - /// from_list([#("b", 2)]) - /// - /// > delete([#("a", 0), #("b", 1)], ["c"]) - /// from_list([#("a", 0), #("b", 1)]) - /// - /// > drop([#("a", 0), #("b", 1)], ["a", "b", "c"]) - /// from_list([]) - /// - pub fn drop(from map: Map(k, v), drop disallowed_keys: List(k)) -> Map(k, v) { - list.fold(disallowed_keys, map, fn(key, acc) { delete(acc, key) }) - } +/// Creates a new map from a given map with all the same entries except any with +/// keys found in a given list. +/// +/// ## Examples +/// +/// > drop([#("a", 0), #("b", 1)], ["a"]) +/// from_list([#("b", 2)]) +/// +/// > delete([#("a", 0), #("b", 1)], ["c"]) +/// from_list([#("a", 0), #("b", 1)]) +/// +/// > drop([#("a", 0), #("b", 1)], ["a", "b", "c"]) +/// from_list([]) +/// +pub fn drop(from map: Map(k, v), drop disallowed_keys: List(k)) -> Map(k, v) { + list.fold(disallowed_keys, map, fn(key, acc) { delete(acc, key) }) +} - /// Creates a new map with one entry updated using a given function. - /// - /// If there was not an entry in the map for the given key then the function - /// gets `Error(Nil)` as its argument, otherwise it gets `Ok(value)`. - /// - /// ## Example - /// - /// > let increment = fn(x) { - /// > case x { - /// > Ok(i) -> i + 1 - /// > Error(Nil) -> 0 - /// > } - /// > } - /// > let map = from_list([#("a", 0)]) - /// > - /// > update(map, "a" increment) - /// from_list([#("a", 1)]) - /// - /// > update(map, "b" increment) - /// from_list([#("a", 0), #("b", 0)]) - /// - pub fn update( - in map: Map(k, v), - update key: k, - with fun: fn(Option(v)) -> v, - ) -> Map(k, v) { - map - |> get(key) - |> option.from_result - |> fun - |> insert(map, key, _) - } +/// Creates a new map with one entry updated using a given function. +/// +/// If there was not an entry in the map for the given key then the function +/// gets `Error(Nil)` as its argument, otherwise it gets `Ok(value)`. +/// +/// ## Example +/// +/// > let increment = fn(x) { +/// > case x { +/// > Ok(i) -> i + 1 +/// > Error(Nil) -> 0 +/// > } +/// > } +/// > let map = from_list([#("a", 0)]) +/// > +/// > update(map, "a" increment) +/// from_list([#("a", 1)]) +/// +/// > update(map, "b" increment) +/// from_list([#("a", 0), #("b", 0)]) +/// +pub fn update( + in map: Map(k, v), + update key: k, + with fun: fn(Option(v)) -> v, +) -> Map(k, v) { + map + |> get(key) + |> option.from_result + |> fun + |> insert(map, key, _) +} - fn do_fold( - list: List(#(k, v)), - initial: acc, - fun: fn(k, v, acc) -> acc, - ) -> acc { - case list { - [] -> initial - [#(k, v), ..tail] -> do_fold(tail, fun(k, v, initial), fun) - } +fn do_fold( + list: List(#(k, v)), + initial: acc, + fun: fn(k, v, acc) -> acc, +) -> acc { + case list { + [] -> initial + [#(k, v), ..tail] -> do_fold(tail, fun(k, v, initial), fun) } +} - /// Combines all entries into a single value by calling a given function on each - /// one. - /// - /// Maps are not ordered so the values are not returned in any specific order. Do - /// not write code that relies on the order entries are used by this function - /// as it may change in later versions of Gleam or Erlang. - /// - /// # Examples - /// - /// > let map = from_list([#("a", 1), #("b", 3), #("c", 9)]) - /// > fold(map, 0, fn(key, value, accumulator) { accumulator + value }) - /// 13 - /// - /// > import gleam/string.{append} - /// > fold(map, "", fn(key, value, accumulator) { append(accumulator, value) }) - /// "abc" - /// - pub fn fold( - over map: Map(k, v), - from initial: acc, - with fun: fn(k, v, acc) -> acc, - ) -> acc { - map - |> to_list - |> do_fold(initial, fun) - } +/// Combines all entries into a single value by calling a given function on each +/// one. +/// +/// Maps are not ordered so the values are not returned in any specific order. Do +/// not write code that relies on the order entries are used by this function +/// as it may change in later versions of Gleam or Erlang. +/// +/// # Examples +/// +/// > let map = from_list([#("a", 1), #("b", 3), #("c", 9)]) +/// > fold(map, 0, fn(key, value, accumulator) { accumulator + value }) +/// 13 +/// +/// > import gleam/string.{append} +/// > fold(map, "", fn(key, value, accumulator) { append(accumulator, value) }) +/// "abc" +/// +pub fn fold( + over map: Map(k, v), + from initial: acc, + with fun: fn(k, v, acc) -> acc, +) -> acc { + map + |> to_list + |> do_fold(initial, fun) } diff --git a/src/gleam_stdlib.js b/src/gleam_stdlib.js index 652b7b5..0cb2417 100644 --- a/src/gleam_stdlib.js +++ b/src/gleam_stdlib.js @@ -258,3 +258,67 @@ export function regex_scan(regex, string) { }); return List.fromArray(matches); } + +export function new_map() { + return new Map(); +} + +export function map_size(map) { + return map.size; +} + +export function map_to_list(map) { + const result = []; + map.forEach(([a, b]) => result.push([JSON.parse(a), b])) +} + +export function map_from_list(list) { + return new Map(list.map(([a, b]) => [JSON.stringify(a), b])); +} + +export function map_has_key(k, map) { + return map.contains(JSON.stringify(k)); +} + +export function map_remove(k, map) { + new Map(map).remove(JSON.stringify(k)); +} + +export function map_filter(f, map) { + const result = new Map(); + map.entries.forEach(([a, b]) => { + if (f(JSON.parse(a))) { + result.set(a, b); + } + }) +} + +export function map_get(from, get) { + from.get(JSON.stringify(get)); +} + +export function map_insert(key, value, map) { + return new Map(map).set(JSON.stringify(key), value); +} + +export function map_keys(map) { + return [...map.keys()].map(key => JSON.parse(key)); +} + +export function map_values(map) { + return [...map.values()]; +} + +export function map_map_values(fn, map) { + const result = new Map(); + map.forEach(([a, b]) => result.set(JSON.stringify(fn(JSON.parse(a))), b)); +} + +export function map_merge(into, merge) { + return new Map(...into, ...merge); +} + +export function map_take(keys, map) { + const result = new Map(); + keys.forEach(key => result.set(JSON.stringify(key), map.get(JSON.stringify(key)))); +}
\ No newline at end of file diff --git a/test/gleam/map_test.gleam b/test/gleam/map_test.gleam index d09a00a..6790166 100644 --- a/test/gleam/map_test.gleam +++ b/test/gleam/map_test.gleam @@ -1,172 +1,170 @@ -if erlang { - import gleam/string - import gleam/should - import gleam/map - import gleam/option.{None, Some} - - pub fn from_list_test() { - [#(4, 0), #(1, 0)] - |> map.from_list - |> map.size - |> should.equal(2) - - [#(1, 0), #(1, 1)] - |> map.from_list - |> should.equal(map.from_list([#(1, 1)])) - } +import gleam/string +import gleam/should +import gleam/map +import gleam/option.{None, Some} + +pub fn from_list_test() { + [#(4, 0), #(1, 0)] + |> map.from_list + |> map.size + |> should.equal(2) + + [#(1, 0), #(1, 1)] + |> map.from_list + |> should.equal(map.from_list([#(1, 1)])) +} - pub fn has_key_test() { - [] - |> map.from_list - |> map.has_key(1) - |> should.be_false - - [#(1, 0)] - |> map.from_list - |> map.has_key(1) - |> should.be_true - - [#(4, 0), #(1, 0)] - |> map.from_list - |> map.has_key(1) - |> should.be_true - - [#(4, 0), #(1, 0)] - |> map.from_list - |> map.has_key(0) - |> should.be_false - } +pub fn has_key_test() { + [] + |> map.from_list + |> map.has_key(1) + |> should.be_false + + [#(1, 0)] + |> map.from_list + |> map.has_key(1) + |> should.be_true + + [#(4, 0), #(1, 0)] + |> map.from_list + |> map.has_key(1) + |> should.be_true + + [#(4, 0), #(1, 0)] + |> map.from_list + |> map.has_key(0) + |> should.be_false +} - pub fn new_test() { - map.new() - |> map.size - |> should.equal(0) +pub fn new_test() { + map.new() + |> map.size + |> should.equal(0) - map.new() - |> map.to_list - |> should.equal([]) - } + map.new() + |> map.to_list + |> should.equal([]) +} - pub fn get_test() { - let proplist = [#(4, 0), #(1, 1)] - let m = map.from_list(proplist) +pub fn get_test() { + let proplist = [#(4, 0), #(1, 1)] + let m = map.from_list(proplist) - m - |> map.get(4) - |> should.equal(Ok(0)) + m + |> map.get(4) + |> should.equal(Ok(0)) - m - |> map.get(1) - |> should.equal(Ok(1)) + m + |> map.get(1) + |> should.equal(Ok(1)) - m - |> map.get(2) - |> should.equal(Error(Nil)) - } + m + |> map.get(2) + |> should.equal(Error(Nil)) +} - pub fn insert_test() { - map.new() - |> map.insert("a", 0) - |> map.insert("b", 1) - |> map.insert("c", 2) - |> should.equal(map.from_list([#("a", 0), #("b", 1), #("c", 2)])) - } +pub fn insert_test() { + map.new() + |> map.insert("a", 0) + |> map.insert("b", 1) + |> map.insert("c", 2) + |> should.equal(map.from_list([#("a", 0), #("b", 1), #("c", 2)])) +} - pub fn map_values_test() { - [#(1, 0), #(2, 1), #(3, 2)] - |> map.from_list - |> map.map_values(fn(k, v) { k + v }) - |> should.equal(map.from_list([#(1, 1), #(2, 3), #(3, 5)])) - } +pub fn map_values_test() { + [#(1, 0), #(2, 1), #(3, 2)] + |> map.from_list + |> map.map_values(fn(k, v) { k + v }) + |> should.equal(map.from_list([#(1, 1), #(2, 3), #(3, 5)])) +} - pub fn keys_test() { - [#("a", 0), #("b", 1), #("c", 2)] - |> map.from_list - |> map.keys - |> should.equal(["a", "b", "c"]) - } +pub fn keys_test() { + [#("a", 0), #("b", 1), #("c", 2)] + |> map.from_list + |> map.keys + |> should.equal(["a", "b", "c"]) +} - pub fn values_test() { - [#("a", 0), #("b", 1), #("c", 2)] - |> map.from_list - |> map.values - |> should.equal([0, 1, 2]) - } +pub fn values_test() { + [#("a", 0), #("b", 1), #("c", 2)] + |> map.from_list + |> map.values + |> should.equal([0, 1, 2]) +} - pub fn take_test() { - [#("a", 0), #("b", 1), #("c", 2)] - |> map.from_list - |> map.take(["a", "b", "d"]) - |> should.equal(map.from_list([#("a", 0), #("b", 1)])) - } +pub fn take_test() { + [#("a", 0), #("b", 1), #("c", 2)] + |> map.from_list + |> map.take(["a", "b", "d"]) + |> should.equal(map.from_list([#("a", 0), #("b", 1)])) +} - pub fn drop_test() { - [#("a", 0), #("b", 1), #("c", 2)] - |> map.from_list - |> map.drop(["a", "b", "d"]) - |> should.equal(map.from_list([#("c", 2)])) - } +pub fn drop_test() { + [#("a", 0), #("b", 1), #("c", 2)] + |> map.from_list + |> map.drop(["a", "b", "d"]) + |> should.equal(map.from_list([#("c", 2)])) +} - pub fn merge_test() { - let a = map.from_list([#("a", 2), #("c", 4), #("d", 3)]) +pub fn merge_test() { + let a = map.from_list([#("a", 2), #("c", 4), #("d", 3)]) - let b = map.from_list([#("a", 0), #("b", 1), #("c", 2)]) + let b = map.from_list([#("a", 0), #("b", 1), #("c", 2)]) - map.merge(a, b) - |> should.equal(map.from_list([#("a", 0), #("b", 1), #("c", 2), #("d", 3)])) + map.merge(a, b) + |> should.equal(map.from_list([#("a", 0), #("b", 1), #("c", 2), #("d", 3)])) - map.merge(b, a) - |> should.equal(map.from_list([#("a", 2), #("b", 1), #("c", 4), #("d", 3)])) - } + map.merge(b, a) + |> should.equal(map.from_list([#("a", 2), #("b", 1), #("c", 4), #("d", 3)])) +} - pub fn delete_test() { - [#("a", 0), #("b", 1), #("c", 2)] - |> map.from_list - |> map.delete("a") - |> map.delete("d") - |> should.equal(map.from_list([#("b", 1), #("c", 2)])) - } +pub fn delete_test() { + [#("a", 0), #("b", 1), #("c", 2)] + |> map.from_list + |> map.delete("a") + |> map.delete("d") + |> should.equal(map.from_list([#("b", 1), #("c", 2)])) +} - pub fn update_test() { - let dict = map.from_list([#("a", 0), #("b", 1), #("c", 2)]) +pub fn update_test() { + let dict = map.from_list([#("a", 0), #("b", 1), #("c", 2)]) - let inc_or_zero = fn(x) { - case x { - Some(i) -> i + 1 - None -> 0 - } + let inc_or_zero = fn(x) { + case x { + Some(i) -> i + 1 + None -> 0 } + } - dict - |> map.update("a", inc_or_zero) - |> should.equal(map.from_list([#("a", 1), #("b", 1), #("c", 2)])) + dict + |> map.update("a", inc_or_zero) + |> should.equal(map.from_list([#("a", 1), #("b", 1), #("c", 2)])) - dict - |> map.update("b", inc_or_zero) - |> should.equal(map.from_list([#("a", 0), #("b", 2), #("c", 2)])) + dict + |> map.update("b", inc_or_zero) + |> should.equal(map.from_list([#("a", 0), #("b", 2), #("c", 2)])) - dict - |> map.update("z", inc_or_zero) - |> should.equal(map.from_list([#("a", 0), #("b", 1), #("c", 2), #("z", 0)])) - } + dict + |> map.update("z", inc_or_zero) + |> should.equal(map.from_list([#("a", 0), #("b", 1), #("c", 2), #("z", 0)])) +} - pub fn fold_test() { - let dict = map.from_list([#("a", 0), #("b", 1), #("c", 2), #("d", 3)]) +pub fn fold_test() { + let dict = map.from_list([#("a", 0), #("b", 1), #("c", 2), #("d", 3)]) - let add = fn(_, v, acc) { v + acc } + let add = fn(_, v, acc) { v + acc } - dict - |> map.fold(0, add) - |> should.equal(6) + dict + |> map.fold(0, add) + |> should.equal(6) - let concat = fn(k, _, acc) { string.append(acc, k) } + let concat = fn(k, _, acc) { string.append(acc, k) } - dict - |> map.fold("", concat) - |> should.equal("abcd") + dict + |> map.fold("", concat) + |> should.equal("abcd") - map.from_list([]) - |> map.fold(0, add) - |> should.equal(0) - } + map.from_list([]) + |> map.fold(0, add) + |> should.equal(0) } |