Skip to content

Commit

Permalink
adding the maps.Diff function
Browse files Browse the repository at this point in the history
  • Loading branch information
zostay committed Jul 14, 2023
1 parent e4aba95 commit 3fef8f1
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 0 deletions.
1 change: 1 addition & 0 deletions Changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ WIP TBD

* Added slices.FirstIndex and slices.GrepIndex.
* Added set.NewSized and set.Diff.
* Added maps.Diff.
* Fixed missing test coverage on generic.FirstNonNil and generic.FirstNonZero.

v0.2.0 2023-07-08
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ There are a lot of common map operations that are missing from the built-in
standard library:

* `Merge(...maps)`
* `Diff(a, b)`

## Generic Sets

Expand Down
32 changes: 32 additions & 0 deletions maps/merge.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package maps

import "github.com/zostay/go-std/generic"

// Merge maps into a single map. Keys in maps later in the list will overwrite
// keys found in earlier maps.
func Merge[K comparable, V any](maps ...map[K]V) map[K]V {
Expand All @@ -11,3 +13,33 @@ func Merge[K comparable, V any](maps ...map[K]V) map[K]V {
}
return out
}

// Diff returns three maps from two. The first map returned is a map of
// key/value pairs where the keys are found in both the first and second input
// maps. The second map returned contains a map of key/value pairs for keys only
// found in the first map. The third map returned contains a map of key/value
// pairs for keys only found in the third map.
//
// If values differ for keys held in common, the value in the first input map
// are kept.
func Diff[K comparable, V any](a, b map[K]V) (common, inFirst, inSecond map[K]V) {
common = make(map[K]V, generic.Max(len(a), len(b)))
inFirst = make(map[K]V, len(a))
inSecond = make(map[K]V, len(b))

for akey, avalue := range a {
if _, found := b[akey]; found {
common[akey] = avalue
} else {
inFirst[akey] = avalue
}
}

for bkey, bvalue := range b {
if _, found := a[bkey]; !found {
inSecond[bkey] = bvalue
}
}

return
}
10 changes: 10 additions & 0 deletions maps/merge_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,13 @@ func TestMerge(t *testing.T) {
"a": 5, "b": 6, "c": 7, "d": 4,
}, maps.Merge(a, b, c))
}

func TestDiff(t *testing.T) {
a := map[string]int{"one": 1, "two": 2, "three": 3, "four": 4}
b := map[string]int{"one": 5, "three": 6, "five": 7, "seven": 8}

c, one, two := maps.Diff(a, b)
assert.Equal(t, map[string]int{"one": 1, "three": 3}, c)
assert.Equal(t, map[string]int{"two": 2, "four": 4}, one)
assert.Equal(t, map[string]int{"five": 7, "seven": 8}, two)
}

0 comments on commit 3fef8f1

Please sign in to comment.