상세 컨텐츠

본문 제목

Golang에는 Set이 없어요...

Dev Type

by ai developer 2024. 8. 29. 20:23

본문

 

Go 언어는 기본적으로 set 데이터 타입을 제공하지 않습니다.

그래서 편리하게 사용하던 set을 사용하고 싶다면, 직접 구현해야 합니다!

 

막상 갑자기 직접 구현하려니 마음이 답답한데, Go에서 제공하는 Map 데이터 타입을 이용해 쉽게 구현할 수 있습니다.

Map은 키, 값을 한쌍으로 갖기 때문에, 키가 중복되면 안됩니다. 

이 원리를 이용하면 쉽게 구현됩니다.

 

map[type]struct{} 를 이용하여 구현하게 됩니다. struct{} 는 빈 구조체로서 메모리를 차지하지 않게 됩니다. 

그래서 map[type]struct{} 를 이용하면 값 없이 키만 저장할 때 사용하기에 제격입니다.

이 때, type에 대해 T comparable을 이용하면 여러 타입의 Set을 소화할 수 있도록 만들 수 있습니다.

 

아래는 구현한 내용입니다. 

package main

type Set[T comparable] map[T]struct{}

func NewSet[T comparable](values []T) Set[T] {
	set := make(Set[T])
	set.Add(values)
	return set
}

func (s Set[T]) Add(values []T) {
	for _, value := range values {
		s[value] = struct{}{}
	}
}

func (s Set[T]) Remove(value T) {
	delete(s, value)
}

func (s Set[T]) Contains(value T) bool {
	_, exists := s[value]
	return exists
}

func (s Set[T]) Size() int {
	return len(s)
}

func (s Set[T]) ToSlice() []T {
	slice := make([]T, 0, len(s))
	for value := range s {
		slice = append(slice, value)
	}
	return slice
}

 

간단히 사용하려면 사실 설명을 보지 않고 바로 복붙해서 사용해도 됩니다.

 

NewSet은 slice(array)를 입력 받아 Add를 통해 Set 구조체에 넣어줍니다.

Add도 slice(array)를 입력 받아 해당 Set 구조체에 value를 키값으로 한 빈 구조체를 설정해 줍니다.

Remove는 키 값을 제거해 주고 Contains는 키 값이 존재하는지 확인해 true, false로 반환하고 Size는 키의 개수를 확인해 줍니다.

그리고 나중에 다시 slice(array)로 변경하고자 할 때는 ToSlice를 이용해 slice로 변환합니다.

 

아래는 실제 사용 예시입니다.

 

package main

func main() {
    // 빈 Set 생성 후 슬라이스로 추가
    s := NewSet([]int{1, 2, 3}) // 여러 값 추가

    // 추가적인 값들을 슬라이스로 추가
    moreValues := []int{4, 5, 6}
    s.Add(moreValues) // 슬라이스를 전달하여 추가

    fmt.Println(s.Contains(1)) // true
    fmt.Println(s.Contains(6)) // true
    fmt.Println(s.Contains(7)) // false

    fmt.Println(s.Size()) // 6

    s.Remove(1)
    fmt.Println(s.Contains(1)) // false

    // 현재 Set의 값을 배열로 변환하여 출력
    fmt.Println(s.ToSlice()) // [2 3 4 5 6]
}

 

Set을 사용하는 것은 본인이 편리한 방식으로 커스텀 해서 구현해 사용해도 됩니다.

도움이 되었으면 좋겠네요. 감사합니다!

300x250

관련글 더보기

댓글 영역