網頁

2022/6/22

Golang 實作Set練習

Go實作一個簡單的Set練習。


Go沒有Set(集合)資料結構,但可以利用map來實作。已有不少優秀的Go Set實作如golang-set,本篇僅是練習。

Set的特性是無順序、元素不重複。

main.go

package main

import (
    "fmt"
    "strings"
)

type Set map[string]bool

func NewSet() *Set {
    return &Set{}
}

func From(slice []string) *Set {
    s := NewSet()
    for _, e := range slice {
        (*s)[e] = true
    }
    return s
}

func (s *Set) Has(e string) bool {
    return (*s)[e]
}

func (s *Set) Put(e string) {
    (*s)[e] = true
}

func (s *Set) Remove(e string) {
    delete(*s, e)
}

func (s *Set) Slice() (slice []string) {
    for k := range *s {
        slice = append(slice, k)
    }
    return
}

func (s *Set) Clear() {
    *s = *NewSet()
}

func (s *Set) Equals(s2 *Set) bool {
    if s2 == nil {
        return false
    }
    if len(*s) != len(*s2) {
        return false
    }
    if s == s2 {
        return true
    }
    for e := range *s2 {
        if !s.Has(e) {
            return false
        }
    }
    return true
}

func (s *Set) String() string {
    return fmt.Sprintf("{%v}", strings.Join(s.Slice(), ","))
}

func main() {
    s1 := From([]string{"a", "b", "a", "d"})
    s2 := From([]string{"a", "b", "d"})

    fmt.Println(s1.Equals(s2)) // true
    fmt.Println(s1)            // {a,b,d}
    fmt.Println(len(*s1))      // 3
    fmt.Println(s1.Has("a"))   // true
    fmt.Println(s1.Has("c"))   // false
    fmt.Println(s1.Slice())    // [a b d]

    s1.Remove("c")
    s1.Remove("b")
    fmt.Println(s1) // {a,d}
    s1.Clear()
    fmt.Println(s1) // {}
}

沒有留言:

張貼留言