Current section
Files
Jump to
Current section
Files
src/gleamy/structures/map.gleam
import gleam/order.{Order}
import gleam/list
import gleamy/structures/tree/red_black_tree_kv as tree
type Map(k, v) =
tree.Tree(k, v)
pub fn new(compare: fn(k, k) -> Order) -> Map(k, v) {
tree.new(compare)
}
pub fn insert(into map: Map(k, v), key key: k, value value: v) -> Map(k, v) {
tree.insert(map, key, value)
}
pub fn find(in map: Map(k, v), key key: k) -> Result(#(k, v), Nil) {
tree.find(map, key)
}
pub fn has_key(in map: Map(k, v), key key: k) -> Bool {
case tree.find(map, key) {
Ok(_) -> True
Error(_) -> False
}
}
pub fn delete(from map: Map(k, v), this key: k) -> Map(k, v) {
tree.delete(map, key)
}
pub fn count(map: Map(k, v)) -> Int {
tree.fold(map, 0, fn(a, _, _) { a + 1 })
}
pub fn fold(
over map: Map(k, v),
from initial: a,
with reducer: fn(a, k, v) -> a,
) -> a {
tree.fold(map, initial, reducer)
}
pub fn filter(in map: Map(k, v), for property: fn(k, v) -> Bool) -> Map(k, v) {
tree.fold(
map,
map,
fn(map, k, v) {
case property(k, v) {
True -> map
False -> tree.delete(map, k)
}
},
)
}
pub fn merge(this first: Map(k, v), and second: Map(k, v)) -> Map(k, v) {
tree.fold(first, second, fn(a, k, v) { tree.insert(a, k, v) })
}
// return the map keeping only keys in the list
pub fn take(from map: Map(k, v), keeping desired: List(k)) -> Map(k, v) {
case desired {
[x, ..xs] ->
case tree.find(map, x) {
Ok(x) -> tree.insert(take(map, xs), x.0, x.1)
Error(_) -> take(map, xs)
}
[] -> tree.clear(map)
}
}
pub fn from_list(
members: List(#(k, v)),
compare: fn(k, k) -> Order,
) -> Map(k, v) {
list.fold(
members,
tree.new(compare),
fn(tree, i) { tree.insert(tree, i.0, i.1) },
)
}
pub fn to_list(map: Map(k, v)) -> List(#(k, v)) {
tree.foldr(map, [], fn(a, k, v) { [#(k, v), ..a] })
}