4

Consider the following map

mymap := make(map[string]string)
mymap["a"] = "one"
mymap["b"] = "two"
mymap["c"] = "one"

How to determine if the values are unique?

One strategy is to iterate through the map, create a slice of the values. Then iterate through the slice to find duplicates. Is there a better way?

2
  • Just true of false indicating the presence of a duplicate value. I am used to using set in python and then checking the lengths. But golang does not support sets. Commented Jul 28, 2019 at 0:01
  • You can use a map as a set. map[string]struct{} would be the most efficient string set type, as the empty struct values will use no memory. Commented Jul 29, 2019 at 13:42

2 Answers 2

9

If you just need true/false of whether there are dupes, without needing to know which values are dupes or how many dupes there are, the most efficient structure to use to track existing values is a map with empty struct values.

See here (pasted below for convenience):

package main

import (
    "fmt"
)

func hasDupes(m map[string]string) bool {
    x := make(map[string]struct{})

    for _, v := range m {
        if _, has := x[v]; has {
            return true
        }
        x[v] = struct{}{}
    }

    return false
}

func main() {
    mapWithDupes := make(map[string]string)
    mapWithDupes["a"] = "one"
    mapWithDupes["b"] = "two"
    mapWithDupes["c"] = "one"

    fmt.Println(hasDupes(mapWithDupes)) // prints true

    mapWithoutDupes := make(map[string]string)
    mapWithoutDupes["a"] = "one"
    mapWithoutDupes["b"] = "two"
    mapWithoutDupes["c"] = "three"

    fmt.Println(hasDupes(mapWithoutDupes)) // prints false
}
Sign up to request clarification or add additional context in comments.

2 Comments

Can you please explain the meaning of struct{}{}
This is a literal of an anonymous empty struct type. To break that down, you're probably familiar with something like type myStruct struct{myField string}; x := myStruct{myField: "foo"}. The empty struct is a struct type with no fields, so you could also imagine something like type emptyStruct struct{}; x := emptyStruct{}. Rather than creating an explicitly-named emptyStruct struct, I can inline the type in which case it will be anonymous (i.e. it has no name), like so: x := struct{}{}. You can also do this with non-empty structs, e.g. x := struct{myField string}{myField: "foo"}.
0
func main() {

    m := map[int]int{
        1: 100,
        2: 200,
        3: 100,
        4: 400,
        6: 200,
        7: 700,
    }
    mNew := make(map[int]int)

    for k, v := range m {
        if val, has := mNew[v]; !has {
            mNew[v] = k
        } else {
            fmt.Println(k, m[k], ",", val, m[val])
        }
    }

swap the map key & value with a new map Second map wont insert duplicate key, so you can find the values

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.