From a92700e93b9692f8c61f15a360d16baea9569c76 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Mon, 6 Nov 2023 20:09:05 +0200 Subject: [PATCH] maps: add maps.merge/2 and maps.merge_in_place/2 generic utility functions (#19776) --- vlib/maps/maps.v | 22 +++++++++++ vlib/maps/maps_test.v | 88 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) diff --git a/vlib/maps/maps.v b/vlib/maps/maps.v index a923fd6ddd..f28804acea 100644 --- a/vlib/maps/maps.v +++ b/vlib/maps/maps.v @@ -68,3 +68,25 @@ pub fn from_array[T](array []T) map[int]T { 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 { + 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 { + res[k] = v + } + return res +} diff --git a/vlib/maps/maps_test.v b/vlib/maps/maps_test.v index 88a673a5b5..11df779f02 100644 --- a/vlib/maps/maps_test.v +++ b/vlib/maps/maps_test.v @@ -107,3 +107,91 @@ fn test_from_array() { 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 + } +}