From 5febea07334b9f08e7902b883ad941abff5bfb4a Mon Sep 17 00:00:00 2001 From: fantasticbin Date: Wed, 13 Nov 2024 14:26:19 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=86=E7=A6=BB=E8=BF=AD=E4=BB=A3=E5=99=A8?= =?UTF-8?q?=E7=A4=BA=E4=BE=8B=E9=9B=86=E5=90=88=E4=B8=8E=E6=9C=89=E5=BA=8F?= =?UTF-8?q?=E9=9B=86=E5=90=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- iterator/set.go | 58 +++++++++++++++++++++++++++++++++++++------- iterator/set_test.go | 2 +- 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/iterator/set.go b/iterator/set.go index 75b3a4d..99799ff 100644 --- a/iterator/set.go +++ b/iterator/set.go @@ -4,23 +4,41 @@ import ( "iter" ) +// Set 集合 type Set[T comparable] struct { + m map[T]struct{} +} + +// OrderedSet 有序集合 +type OrderedSet[T comparable] struct { ordered []T // 用于保持顺序 - m map[T]struct{} + Set[T] } -func NewSet[T comparable]() *Set[T] { - return &Set[T]{make([]T, 0), make(map[T]struct{})} +func NewSet[T comparable]() Set[T] { + return Set[T]{make(map[T]struct{})} } -func (s *Set[T]) Add(e T) { +func NewOrderedSet[T comparable]() *OrderedSet[T] { + return &OrderedSet[T]{make([]T, 0), NewSet[T]()} +} + +func (s Set[T]) Add(e T) { + s.m[e] = struct{}{} +} + +func (s *OrderedSet[T]) Add(e T) { if !s.Contains(e) { s.ordered = append(s.ordered, e) } s.m[e] = struct{}{} } -func (s *Set[T]) Remove(e T) { +func (s Set[T]) Remove(e T) { + delete(s.m, e) +} + +func (s *OrderedSet[T]) Remove(e T) { for k, v := range s.ordered { if v == e { s.ordered = append(s.ordered[:k], s.ordered[k+1:]...) @@ -31,23 +49,45 @@ func (s *Set[T]) Remove(e T) { delete(s.m, e) } -func (s *Set[T]) Contains(e T) bool { +func (s Set[T]) Contains(e T) bool { _, ok := s.m[e] return ok } -func (s *Set[T]) Len() int { +func (s Set[T]) Len() int { return len(s.m) } -func (s *Set[T]) All() iter.Seq[T] { +func (s Set[T]) All() iter.Seq[T] { + return s.FilterMap(func(T) bool { + return true + }) +} + +// All 有序集合的推迭代器,该方法不能省略,否则会走到子集合的FilterMap方法中去 +func (s *OrderedSet[T]) All() iter.Seq[T] { return s.FilterMap(func(T) bool { return true }) } // FilterMap 筛选迭代 -func (s *Set[T]) FilterMap(fn func(T) bool) iter.Seq[T] { +func (s Set[T]) FilterMap(fn func(T) bool) iter.Seq[T] { + return func(yield func(T) bool) { + for v := range s.m { + if !fn(v) { + continue + } + + if !yield(v) { + return + } + } + } +} + +// FilterMap 筛选迭代 +func (s *OrderedSet[T]) FilterMap(fn func(T) bool) iter.Seq[T] { return func(yield func(T) bool) { // 迭代有序切片 for _, v := range s.ordered { diff --git a/iterator/set_test.go b/iterator/set_test.go index 74947ac..cfd3fad 100644 --- a/iterator/set_test.go +++ b/iterator/set_test.go @@ -8,7 +8,7 @@ import ( ) func TestSet(t *testing.T) { - s := NewSet[string]() + s := NewOrderedSet[string]() list := []string{ "fantasticbin", "phper",