Initial project import
This commit is contained in:
commit
23f2d29e32
11957 files changed
+1754577
No files matched your search
@@ -0,0 +1,3 @@
|
||||
## Description
|
||||
|
||||
`maps` is a module that provides utility functions to make working with maps easier.
|
||||
@@ -0,0 +1,119 @@
|
||||
module maps
|
||||
|
||||
// filter filters map entries by the given predicate function
|
||||
pub fn filter[K, V](m map[K]V, f fn (key K, val V) bool) map[K]V {
|
||||
mut mp := map[K]V{}
|
||||
|
||||
for k, v in m {
|
||||
$if V is $interface {
|
||||
if f(k, unsafe { v }) {
|
||||
mp[k] = v
|
||||
}
|
||||
} $else {
|
||||
if f(k, v) {
|
||||
mp[k] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mp
|
||||
}
|
||||
|
||||
// to_array maps map entries into one-dimensional array
|
||||
pub fn to_array[K, V, I](m map[K]V, f fn (key K, val V) I) []I {
|
||||
mut a := []I{cap: m.len}
|
||||
|
||||
for k, v in m {
|
||||
$if V is $interface {
|
||||
a << f(k, unsafe { v })
|
||||
} $else {
|
||||
a << f(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
return a
|
||||
}
|
||||
|
||||
// flat_map maps map entries into arrays and flattens into a one-dimensional array
|
||||
pub fn flat_map[K, V, I](m map[K]V, f fn (key K, val V) []I) []I {
|
||||
mut a := []I{cap: m.len}
|
||||
|
||||
for k, v in m {
|
||||
$if V is $interface {
|
||||
a << f(k, unsafe { v })
|
||||
} $else {
|
||||
a << f(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
return a
|
||||
}
|
||||
|
||||
// to_map maps map entries into new entries and constructs a new map
|
||||
pub fn to_map[K, V, X, Y](m map[K]V, f fn (key K, val V) (X, Y)) map[X]Y {
|
||||
mut mp := map[X]Y{}
|
||||
|
||||
for k, v in m {
|
||||
$if V is $interface {
|
||||
x, y := f(k, unsafe { v })
|
||||
mp[x] = y
|
||||
} $else {
|
||||
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[K, V](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[T](array []T) map[int]T {
|
||||
mut mp := map[int]T{}
|
||||
|
||||
for i, e in array {
|
||||
mp[i] = e
|
||||
}
|
||||
|
||||
return mp
|
||||
}
|
||||
|
||||
// merge_in_place merges all elements of `m2` into the mutable map `m1`.
|
||||
// If a key exists in both maps, the value from `m1` will be overwritten by the
|
||||
// value from `m2`.
|
||||
// Note that this function modifes `m1`, while `m2` will not be.
|
||||
pub fn merge_in_place[K, V](mut m1 map[K]V, m2 map[K]V) {
|
||||
for k, v in m2 {
|
||||
$if v is $map {
|
||||
m1[k] = v.clone()
|
||||
} $else {
|
||||
m1[k] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// merge produces a map, that is the result of merging the first map `m1`,
|
||||
// with the second map `m2`. If a key exists in both maps, the value from m2,
|
||||
// will override the value from m1.
|
||||
// The original maps `m1` and `m2`, will not be modified. The return value is a new map.
|
||||
pub fn merge[K, V](m1 map[K]V, m2 map[K]V) map[K]V {
|
||||
mut res := m1.clone()
|
||||
for k, v in m2 {
|
||||
$if v is $map {
|
||||
res[k] = v.clone()
|
||||
} $else {
|
||||
res[k] = v
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import maps
|
||||
|
||||
fn test_main() {
|
||||
// mmm map declaration as mutable
|
||||
mut mmm := map[string]map[string]int{}
|
||||
|
||||
// adding values to the map mmm
|
||||
mmm['greet'] = {
|
||||
'hello': 0
|
||||
}
|
||||
mmm['place'] = {
|
||||
'world': 1
|
||||
}
|
||||
mmm['color']['orange'] = 2
|
||||
|
||||
// printing the map mmm
|
||||
assert mmm.str() == "{'greet': {'hello': 0}, 'place': {'world': 1}, 'color': {'orange': 2}}"
|
||||
|
||||
// mmm2 map declaration as const
|
||||
mmm2 := {
|
||||
'name': {
|
||||
'Diego': 3
|
||||
}
|
||||
}
|
||||
|
||||
// printing the map mmm2
|
||||
assert mmm2.str() == "{'name': {'Diego': 3}}"
|
||||
|
||||
// Using the maps module functions
|
||||
// use of maps.merge is commented but its behavior is the same as merge_in_place
|
||||
// mmm = maps.merge(mmm, mmm2)
|
||||
maps.merge_in_place(mut mmm, mmm2)
|
||||
|
||||
// printing again mmm to the standard output
|
||||
assert mmm.str() == "{'greet': {'hello': 0}, 'place': {'world': 1}, 'color': {'orange': 2}, 'name': {'Diego': 3}}"
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
module maps
|
||||
|
||||
interface TestValue {
|
||||
value() string
|
||||
}
|
||||
|
||||
struct TestValueImpl {
|
||||
raw string
|
||||
}
|
||||
|
||||
fn (v TestValueImpl) value() string {
|
||||
return v.raw
|
||||
}
|
||||
|
||||
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_helpers_with_interface_map_values() {
|
||||
m1 := {
|
||||
'a': TestValue(TestValueImpl{'bc'})
|
||||
'd': TestValue(TestValueImpl{'ef'})
|
||||
'g': TestValue(TestValueImpl{'hi'})
|
||||
}
|
||||
filtered := filter(m1, fn (k string, v TestValue) bool {
|
||||
return k == 'a' || v.value() == 'ef'
|
||||
})
|
||||
assert filtered.len == 2
|
||||
assert filtered['a'].value() == 'bc'
|
||||
assert filtered['d'].value() == 'ef'
|
||||
assert to_array(m1, fn (k string, v TestValue) string {
|
||||
return '${k}${v.value()}'
|
||||
}) == ['abc', 'def', 'ghi']
|
||||
assert flat_map[string, TestValue, string](m1, fn (k string, v TestValue) []string {
|
||||
return [k, v.value()]
|
||||
}) == ['a', 'bc', 'd', 'ef', 'g', 'hi']
|
||||
assert to_map[string, TestValue, string, string](m1, fn (k string, v TestValue) (string, string) {
|
||||
return k, v.value()
|
||||
}) == {
|
||||
'a': 'bc'
|
||||
'd': 'ef'
|
||||
'g': 'hi'
|
||||
}
|
||||
}
|
||||
|
||||
fn test_flat_map() {
|
||||
m1 := {
|
||||
1: [2, 3]
|
||||
4: [5, 6]
|
||||
7: [8, 9]
|
||||
}
|
||||
assert flat_map[int, []int, int](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[int, string, string, int](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'
|
||||
}
|
||||
}
|
||||
|
||||
fn test_merge_in_place() {
|
||||
mut m1 := {
|
||||
'abc': 'def'
|
||||
'aa': 'bb'
|
||||
}
|
||||
m2 := {
|
||||
'xyz': 'zyx'
|
||||
'aa': 'dd'
|
||||
}
|
||||
merge_in_place(mut m1, m2)
|
||||
assert m1 == {
|
||||
'abc': 'def'
|
||||
'aa': 'dd'
|
||||
'xyz': 'zyx'
|
||||
}
|
||||
assert m2 == {
|
||||
'xyz': 'zyx'
|
||||
'aa': 'dd'
|
||||
}
|
||||
|
||||
mut im1 := {
|
||||
11: 22
|
||||
33: 44
|
||||
}
|
||||
im2 := {
|
||||
55: 66
|
||||
33: 999
|
||||
}
|
||||
merge_in_place(mut im1, im2)
|
||||
assert im1 == {
|
||||
11: 22
|
||||
33: 999
|
||||
55: 66
|
||||
}
|
||||
assert im2 == {
|
||||
55: 66
|
||||
33: 999
|
||||
}
|
||||
}
|
||||
|
||||
fn test_merge() {
|
||||
m1 := {
|
||||
'abc': 'def'
|
||||
'aa': 'bb'
|
||||
}
|
||||
m2 := {
|
||||
'xyz': 'zyx'
|
||||
'aa': 'dd'
|
||||
}
|
||||
res := merge(m1, m2)
|
||||
assert res == {
|
||||
'abc': 'def'
|
||||
'aa': 'dd'
|
||||
'xyz': 'zyx'
|
||||
}
|
||||
assert m1 == {
|
||||
'abc': 'def'
|
||||
'aa': 'bb'
|
||||
}
|
||||
assert m2 == {
|
||||
'xyz': 'zyx'
|
||||
'aa': 'dd'
|
||||
}
|
||||
|
||||
mut im1 := {
|
||||
11: 22
|
||||
33: 44
|
||||
}
|
||||
im2 := {
|
||||
55: 66
|
||||
33: 999
|
||||
}
|
||||
ires := merge(im1, im2)
|
||||
assert im1 == {
|
||||
11: 22
|
||||
33: 44
|
||||
}
|
||||
assert im2 == {
|
||||
55: 66
|
||||
33: 999
|
||||
}
|
||||
assert ires == {
|
||||
11: 22
|
||||
33: 999
|
||||
55: 66
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user