Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Slice as a key in map

Tags:

go

Is it possible to use slices as keys?

There is my attempt:

h := map[[]string]string{
  []string{"a", "b"} : "ab",
}

the compiler gives me an error invalid map key type []string. So either it's not possible or I declared it incorrectly (if so, what would be a correct way?).

like image 473
ave Avatar asked Nov 30 '13 06:11

ave


People also ask

Can array be key in map Golang?

There is our answer, slices can't be key in Map, but an array can be.

What are some of the advantages of using structs over maps and slices?

A struct is just often more useful in Go, since the fields and their types are statically known, as well as being more efficient, since fields are stored directly and at known offsets which don't need to be computed on each access.

How do you check if a key exists in a map Golang?

Check if Key is Present in Map in Golang To check if specific key is present in a given map in Go programming, access the value for the key in map using map[key] expression. This expression returns the value if present, and a boolean value representing if the key is present or not.


4 Answers

However, it is possible to use arrays as map keys:

package main

import "fmt"

func main() {
    m := make(map[[2]int]bool)
    m[[2]int{1, 2}] = false
    fmt.Printf("%v", m)
}
like image 176
Bill DeRose Avatar answered Oct 04 '22 13:10

Bill DeRose


No, slices cannot be used as map keys as they have no equality defined.

like image 41
Volker Avatar answered Oct 04 '22 12:10

Volker


Volker already told that this is not possible and I will give a little bit more details of why is it so with examples from the spec.


Map spec tells you:

The comparison operators == and != must be fully defined for operands of the key type; thus the key type must not be a function, map, or slice.

It already tells you that the slice can't be a key, but you could have checked it also in the comparison spec:

Slice, map, and function values are not comparable.


This means that also slice can't be a key, an array can be a key. For example you can write:

h := map[[2]string]string{
  [2]string{"a", "b"} : "ab",
}
like image 19
Salvador Dali Avatar answered Oct 04 '22 13:10

Salvador Dali


Depending on your requirements and the complexity of your data, you could use a string as a map key and then use a hash of your slice as the map key.

The nice thing is you can use this technique with anything that can be converted to or from a slice of bytes.

Here's a quick way to convert your slice of strings into a slice of bytes:

[]byte(strings.Join([]string{},""))

Here's an example using SHA1:

type ByteSliceMap struct {
    buf *bytes.Buffer
    m   map[string][]byte
}

func (b *ByteSliceMap) key(buf []byte) string {
    h := sha1.New()
    h.Write(buf)
    sum := h.Sum(nil)
    return fmt.Sprintf("%x", sum)
}

func (t *ByteSliceMap) value(key []byte) (value []byte, ok bool) {
    value, ok = t.m[t.key(key)]
    return
}


func (t *ByteSliceMap) add(key, value []byte) {
    if t.m == nil {
        t.m = make(map[string][]byte)
    }
    t.m[t.key(key)] = value
}

Working version

like image 5
Carl Avatar answered Oct 04 '22 13:10

Carl