< up >
2023-12-14

Hashsets in go

tl;dr

var hashSet map[string]struct{}

Introduction

The term HashSet is a data structure from the Java universe describing a value-less HashMap1. It is perfect when uniqueness is needed but avoids the overhead of a value. Using golang they can be constructed using an ordinary map and an empty struct:

var hashSet map[key]struct{}

Use Cases

The key can be any supported type. Interestingly, next to the primitive ones (int, string,…), struct types are also supported. This comes quite handy when making custom cache keys.

Visited nodes

When searching through a grid or a graph, a HashSet can be used to avoid loops by caching already seen points:

type Point struct{
  x,y int
}

var visited map[Point]struct{}

Uniqueness

Another use-case would be to ensure uniqueness over a dataset. E.g. the bash command uniq reads a stream from stdin and only prints every line once to stdout:

package main

import (
    "bufio"
    "fmt"
    "os"
)

func main() {
    set := make(map[string]struct{})

    scanner := bufio.NewScanner(os.Stdin)
    for scanner.Scan() {
        if _, found := set[scanner.Text()]; !found {
            set[scanner.Text()] = struct{}{}
            fmt.Println(scanner.Text())
        }
    }
}

Turning…

 I've experiments to run.
 There is research to be done.
 On the people who are
 still alive.
 And believe me I am
 still alive.
 I'm doing science and I'm
 still alive.
 I feel fantastic and I'm
 still alive.
 While you're dying I'll be
 still alive.
 And when you're dead I will be
 still alive.

…via cat lyrics| go run unique.go to…

I've experiments to run.
There is research to be done.
On the people who are
still alive.
And believe me I am
I'm doing science and I'm
I feel fantastic and I'm
While you're dying I'll be
And when you're dead I will be

References


  1. Same as map in golang, dict in python, associative arrays in php