diff --git a/vlib/maps/README.md b/vlib/maps/README.md new file mode 100644 index 0000000000..a6eb9a91c4 --- /dev/null +++ b/vlib/maps/README.md @@ -0,0 +1,3 @@ +## Description: + +`maps` is a module that provides utility functions to make working with maps easier. diff --git a/vlib/maps/maps.v b/vlib/maps/maps.v new file mode 100644 index 0000000000..e329e0aedc --- /dev/null +++ b/vlib/maps/maps.v @@ -0,0 +1,70 @@ +module maps + +// filter filters map entries by the given predicate function +pub fn filter(m map[K]V, f fn (K, V) bool) map[K]V { + mut mp := map[K]V{} + + for k, v in m { + if f(k, v) { + mp[k] = v + } + } + + return mp +} + +// to_array maps map entries into one-dimensional array +pub fn to_array(m map[K]V, f fn (K, V) I) []I { + mut a := []I{cap: m.len} + + for k, v in m { + a << f(k, v) + } + + return a +} + +// flatten maps map entries into arrays and flattens into a one-dimensional array +pub fn flatten(m map[K]V, f fn (K, V) []I) []I { + mut a := []I{cap: m.len} + + for k, v in m { + a << f(k, v) + } + + return a +} + +// to_map maps map entries into new entries and constructs a new map +pub fn to_map(m map[K]V, f fn (K, V) (X, Y)) map[X]Y { + mut mp := map[X]Y{} + + for k, v in m { + x, y := f(k, v) + mp[x] = y + } + + return mp +} + +// invert returns a new map, created by swapping key to value and vice versa for each entry. +pub fn invert(m map[K]V) map[V]K { + mut mp := map[V]K{} + + for k, v in m { + mp[v] = k + } + + return mp +} + +// from_array maps array into map with index to element per entry +pub fn from_array(a []T) map[int]T { + mut mp := map[int]T{} + + for i, e in a { + mp[i] = e + } + + return mp +} diff --git a/vlib/maps/maps_test.v b/vlib/maps/maps_test.v new file mode 100644 index 0000000000..7d6e3d4130 --- /dev/null +++ b/vlib/maps/maps_test.v @@ -0,0 +1,109 @@ +module maps + +fn test_filter() { + m1 := { + 0: 'ab' + 1: 'bc' + 2: 'cd' + 3: 'de' + 4: 'ef' + 5: 'fg' + } + assert filter(m1, fn (k int, v string) bool { + return k % 2 == 0 + }) == { + 0: 'ab' + 2: 'cd' + 4: 'ef' + } + assert filter(m1, fn (k int, v string) bool { + return v.contains('b') || v.contains('c') + }) == { + 0: 'ab' + 1: 'bc' + 2: 'cd' + } +} + +fn test_to_array() { + m1 := { + `a`: 'bc' + `d`: 'ef' + `g`: 'hi' + } + assert to_array(m1, fn (k rune, v string) string { + return '$k$v' + }) == ['abc', 'def', 'ghi'] +} + +fn test_flatten() { + m1 := { + 1: [2, 3] + 4: [5, 6] + 7: [8, 9] + } + assert flatten(m1, fn (k int, v []int) []int { + mut a := [k] + a << v + return a + }) == [1, 2, 3, 4, 5, 6, 7, 8, 9] +} + +fn test_to_map() { + m1 := { + 0: '0' + 1: '1' + 2: '2' + 3: '3' + 4: '4' + 5: '5' + } + assert to_map(m1, fn (k int, v string) (string, int) { + return v, k + }) == { + '0': 0 + '1': 1 + '2': 2 + '3': 3 + '4': 4 + '5': 5 + } +} + +fn test_invert() { + m1 := { + 0: '0' + 1: '1' + 2: '2' + 3: '3' + 4: '4' + 5: '5' + } + assert invert(m1) == { + '0': 0 + '1': 1 + '2': 2 + '3': 3 + '4': 4 + '5': 5 + } +} + +fn test_from_array() { + a1 := [ + 'a', + 'b', + 'c', + 'd', + 'e', + 'f', + ] + assert from_array(a1) == { + 0: 'a' + 1: 'b' + 2: 'c' + 3: 'd' + 4: 'e' + 5: 'f' + } +}