# Shorter/clearer way of extracting common and unique elements from a map

Hi Gophers,
I once again seek your guidance in solving this problem. The problem is as follows:
Given two maps, write a program that would return common elements (if any) and unique elements(if any) in two separate maps.
Here’s what I’ve done so far:

``````package main

import "fmt"

func main() {
fmt.Println("vim-go")

firstMap := map[string]string{
"first":    "Pritesh",
"middle":   "Manohar",
"last":     "Ugrankar",
"city":     "Bangalore",
"building": "Ittina Neela",
}
secondMap := map[string]string{
"first":    "Pritesh",
"middle":   "Manohar",
"last":     "Ugrankar",
"location": "ECity",
}

common, unique := unique(firstMap, secondMap)
fmt.Println("First map contains:", firstMap)
fmt.Println("Second map contains:", secondMap)
fmt.Println("Common elements are:", common)
fmt.Println("Unique elements are:", unique)
}

func unique(first map[string]string, second map[string]string) (map[string]string, map[string]string) {
commonMap := make(map[string]string)
uniqueMap := make(map[string]string)

for key, _ := range first {
uniqueMap[key] = first[key]
}
for key, _ := range second {
if _, ok := uniqueMap[key]; ok == true {
delete(uniqueMap, key)
commonMap[key] = second[key]
} else {
uniqueMap[key] = second[key]
}
}

return commonMap, uniqueMap
}
``````

And I get the answer as expected:

``````pritesh@debian:~/go/src/github.com/pritesh-ugrankar/umaps\$ go run main.go
vim-go
First map contains: map[building:Ittina Neela city:Bangalore first:Pritesh last:Ugrankar middle:Manohar]
Second map contains: map[first:Pritesh last:Ugrankar location:ECity middle:Manohar]
Common elements are: map[first:Pritesh last:Ugrankar middle:Manohar]
Unique elements are: map[building:Ittina Neela city:Bangalore location:ECity]
pritesh@debian:~/go/src/github.com/pritesh-ugrankar/umaps\$
``````

My problem is with the following section in the code:

``````for key, _ := range second {
if _, ok := uniqueMap[key]; ok == true {
delete(uniqueMap, key)
commonMap[key] = second[key]
} else {
uniqueMap[key] = second[key]
``````

Problem is if I remove the “else” loop, then the unique key from the second map does not get added to the unique map. I’ve tried everything but nothing works except this, and this looks really ugly like a shoddy workaround.
How can I make it better??

2 Likes

What I love about Go is simplicity as driving force( Experiment, Simplify, Ship)
You can simplify your function just doing something like this :

``````func unique(first map[string]string, second map[string]string) (map[string]string, map[string]string) {
commonMap := make(map[string]string)
uniqueMap := make(map[string]string)

for key, value := range first {
// Check if unique or not
if   _, ok := second[key]; ok {
// Exists in second, so it is common
commonMap[key] = value
} else {
// Does not exist in secodn, it is unique
uniqueMap[key] = value
}
}

return commonMap, uniqueMap
}``````
2 Likes

One of those “dammit why couldn’t I think like this” moment for me.
I’ve learnt far more from your answers than any book or video.

1 Like

2 Likes

1 Like

Hi Yamil,
I tried the code you pasted, but it misses some values:
Here’s the code (I’ve commented out my code and input yours)

``````package main

import "fmt"

func main() {
fmt.Println("vim-go")

firstMap := map[string]string{
"first":    "Pritesh",
"middle":   "Manohar",
"last":     "Ugrankar",
"city":     "Bangalore",
"building": "Ittina Neela",
}
secondMap := map[string]string{
"first":    "Pritesh",
"middle":   "Manohar",
"last":     "Ugrankar",
"location": "ECity",
}

common, unique := unique(firstMap, secondMap)
fmt.Println("First map contains:", firstMap)
fmt.Println("Second map contains:", secondMap)
fmt.Println("Common elements are:", common)
fmt.Println("Unique elements are:", unique)
}

func unique(first map[string]string, second map[string]string) (map[string]string, map[string]string) {
commonMap := make(map[string]string)
uniqueMap := make(map[string]string)

/*
for key, _ := range first {
uniqueMap[key] = first[key]
}
for key, _ := range second {
if _, ok := uniqueMap[key]; ok == true {
delete(uniqueMap, key)
commonMap[key] = second[key]
} else {
uniqueMap[key] = second[key]
}
}
*/
for key, value := range first {
// Check if unique or not
if _, ok := second[key]; ok {
// Exists in second, so it is common
commonMap[key] = value
} else {
// Does not exist in secodn, it is unique
uniqueMap[key] = value
}
}
return commonMap, uniqueMap
}
``````

And the output is:

``````pritesh@debian:~/go/src/github.com/pritesh-ugrankar/umaps\$ go run main.go
vim-go
First map contains: map[building:Ittina Neela city:Bangalore first:Pritesh last:Ugrankar middle:Manohar]
Second map contains: map[first:Pritesh last:Ugrankar **location:ECity** middle:Manohar]
Common elements are: map[first:Pritesh last:Ugrankar middle:Manohar]
Unique elements are: map[building:Ittina Neela city:Bangalore]
``````

Note that the `location:ECity` entry is missing. (I’ve highlighted it with ** in the code output).

2 Likes

OK.
The only check is from first map to the second, I mean, we only check if a element is in map first and not in the second, but the opposite is not done.
Just add the following code before returning maps in the unique function

``````// Now search for elements only in second mao and not in first map
for key, value := range second {
if _, ok := first[key]; !ok {
uniqueMap[key] = value
}
}

return commonMap, uniqueMap``````
3 Likes

Hi Yamil,
Indeed. Right after typing the question, I tried to solve it myself and wrote almost the same code except I wrote `ok == false` instead of `!ok` (same thing, different syntax).

Thank you once again Sir.

2 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.