github.com/enetx/g@v1.0.80/set.go (about)

     1  package g
     2  
     3  import "fmt"
     4  
     5  // NewSet creates a new Set of the specified size or an empty Set if no size is provided.
     6  func NewSet[T comparable](size ...Int) Set[T] {
     7  	if len(size) == 0 {
     8  		return make(Set[T], 0)
     9  	}
    10  
    11  	return make(Set[T], size[0])
    12  }
    13  
    14  // SetOf creates a new generic set containing the provided elements.
    15  func SetOf[T comparable](values ...T) Set[T] {
    16  	set := NewSet[T](Int(len(values)))
    17  	for _, v := range values {
    18  		set.Add(v)
    19  	}
    20  
    21  	return set
    22  }
    23  
    24  // SetMap applies the given function to each element of a Set and returns a new Set
    25  // containing the transformed values.
    26  //
    27  // Parameters:
    28  //
    29  // - s: The input Set.
    30  // - fn: The function to apply to each element of the input Set.
    31  //
    32  // Returns:
    33  //
    34  // A new Set containing the results of applying the function to each element of the input Set.
    35  func SetMap[T, U comparable](s Set[T], fn func(T) U) Set[U] { return mapSet(s.Iter(), fn).Collect() }
    36  
    37  // Iter returns an iterator (SeqSet[T]) for the Set, allowing for sequential iteration
    38  // over its elements. It is commonly used in combination with higher-order functions,
    39  // such as 'ForEach' or 'SetMap', to perform operations on each element of the Set.
    40  //
    41  // Returns:
    42  //
    43  // A SeqSet[T], which can be used for sequential iteration over the elements of the Set.
    44  //
    45  // Example usage:
    46  //
    47  //	iter := g.SetOf(1, 2, 3).Iter()
    48  //	iter.ForEach(func(val T) {
    49  //	    fmt.Println(val) // Replace this with the function logic you need.
    50  //	})
    51  //
    52  // The 'Iter' method provides a convenient way to traverse the elements of a Set
    53  // in a functional style, enabling operations like mapping or filtering.
    54  func (s Set[T]) Iter() SeqSet[T] { return ToSeqSet(s) }
    55  
    56  // Add adds the provided elements to the set and returns the modified set.
    57  func (s Set[T]) Add(values ...T) Set[T] {
    58  	for _, v := range values {
    59  		s[v] = struct{}{}
    60  	}
    61  
    62  	return s
    63  }
    64  
    65  // Remove removes the specified values from the Set.
    66  func (s Set[T]) Remove(values ...T) Set[T] {
    67  	for _, v := range values {
    68  		delete(s, v)
    69  	}
    70  
    71  	return s
    72  }
    73  
    74  // Len returns the number of values in the Set.
    75  func (s Set[T]) Len() Int { return Int(len(s)) }
    76  
    77  // Contains checks if the Set contains the specified value.
    78  func (s Set[T]) Contains(v T) bool {
    79  	_, ok := s[v]
    80  	return ok
    81  }
    82  
    83  // ContainsAny checks if the Set contains any element from another Set.
    84  func (s Set[T]) ContainsAny(other Set[T]) bool {
    85  	for v := range other {
    86  		if s.Contains(v) {
    87  			return true
    88  		}
    89  	}
    90  
    91  	return false
    92  }
    93  
    94  // ContainsAll checks if the Set contains all elements from another Set.
    95  func (s Set[T]) ContainsAll(other Set[T]) bool {
    96  	if len(s) < len(other) {
    97  		return false
    98  	}
    99  
   100  	for v := range other {
   101  		if !s.Contains(v) {
   102  			return false
   103  		}
   104  	}
   105  
   106  	return true
   107  }
   108  
   109  // Clone creates a new Set that is a copy of the original Set.
   110  func (s Set[T]) Clone() Set[T] { return s.Iter().Collect() }
   111  
   112  // ToSlice returns a new Slice with the same elements as the Set[T].
   113  func (s Set[T]) ToSlice() Slice[T] {
   114  	sl := NewSlice[T](0, s.Len())
   115  	s.Iter().ForEach(func(v T) { sl = append(sl, v) })
   116  
   117  	return sl
   118  }
   119  
   120  // Intersection returns the intersection of the current set and another set, i.e., elements
   121  // present in both sets.
   122  //
   123  // Parameters:
   124  //
   125  // - other Set[T]: The other set to calculate the intersection with.
   126  //
   127  // Returns:
   128  //
   129  // - Set[T]: A new Set containing the intersection of the two sets.
   130  //
   131  // Example usage:
   132  //
   133  //	s1 := g.SetOf(1, 2, 3, 4, 5)
   134  //	s2 := g.SetOf(4, 5, 6, 7, 8)
   135  //	intersection := s1.Intersection(s2)
   136  //
   137  // The resulting intersection will be: [4, 5].
   138  func (s Set[T]) Intersection(other Set[T]) SeqSet[T] {
   139  	if len(s) <= len(other) {
   140  		return intersection(s.Iter(), other)
   141  	}
   142  
   143  	return intersection(other.Iter(), s)
   144  }
   145  
   146  // Difference returns the difference between the current set and another set,
   147  // i.e., elements present in the current set but not in the other set.
   148  //
   149  // Parameters:
   150  //
   151  // - other Set[T]: The other set to calculate the difference with.
   152  //
   153  // Returns:
   154  //
   155  // - Set[T]: A new Set containing the difference between the two sets.
   156  //
   157  // Example usage:
   158  //
   159  //	s1 := g.SetOf(1, 2, 3, 4, 5)
   160  //	s2 := g.SetOf(4, 5, 6, 7, 8)
   161  //	diff := s1.Difference(s2)
   162  //
   163  // The resulting diff will be: [1, 2, 3].
   164  func (s Set[T]) Difference(other Set[T]) SeqSet[T] { return difference(s.Iter(), other) }
   165  
   166  // Union returns a new set containing the unique elements of the current set and the provided
   167  // other set.
   168  //
   169  // Parameters:
   170  //
   171  // - other Set[T]: The other set to create the union with.
   172  //
   173  // Returns:
   174  //
   175  // - Set[T]: A new Set containing the unique elements of the current set and the provided
   176  // other set.
   177  //
   178  // Example usage:
   179  //
   180  //	s1 := g.SetOf(1, 2, 3)
   181  //	s2 := g.SetOf(3, 4, 5)
   182  //	union := s1.Union(s2)
   183  //
   184  // The resulting union set will be: [1, 2, 3, 4, 5].
   185  func (s Set[T]) Union(other Set[T]) SeqSet[T] {
   186  	if len(s) > len(other) {
   187  		return s.Iter().Chain(other.Difference(s))
   188  	}
   189  
   190  	return other.Iter().Chain(s.Difference(other))
   191  }
   192  
   193  // SymmetricDifference returns the symmetric difference between the current set and another
   194  // set, i.e., elements present in either the current set or the other set but not in both.
   195  //
   196  // Parameters:
   197  //
   198  // - other Set[T]: The other set to calculate the symmetric difference with.
   199  //
   200  // Returns:
   201  //
   202  // - Set[T]: A new Set containing the symmetric difference between the two sets.
   203  //
   204  // Example usage:
   205  //
   206  //	s1 := g.SetOf(1, 2, 3, 4, 5)
   207  //	s2 := g.SetOf(4, 5, 6, 7, 8)
   208  //	symDiff := s1.SymmetricDifference(s2)
   209  //
   210  // The resulting symDiff will be: [1, 2, 3, 6, 7, 8].
   211  func (s Set[T]) SymmetricDifference(other Set[T]) SeqSet[T] {
   212  	return s.Difference(other).Chain(other.Difference(s))
   213  }
   214  
   215  // Subset checks if the current set 's' is a subset of the provided 'other' set.
   216  // A set 's' is a subset of 'other' if all elements of 's' are also elements of 'other'.
   217  //
   218  // Parameters:
   219  //
   220  // - other Set[T]: The other set to compare with.
   221  //
   222  // Returns:
   223  //
   224  // - bool: true if 's' is a subset of 'other', false otherwise.
   225  //
   226  // Example usage:
   227  //
   228  //	s1 := g.SetOf(1, 2, 3)
   229  //	s2 := g.SetOf(1, 2, 3, 4, 5)
   230  //	isSubset := s1.Subset(s2) // Returns true
   231  func (s Set[T]) Subset(other Set[T]) bool { return other.ContainsAll(s) }
   232  
   233  // Superset checks if the current set 's' is a superset of the provided 'other' set.
   234  // A set 's' is a superset of 'other' if all elements of 'other' are also elements of 's'.
   235  //
   236  // Parameters:
   237  //
   238  // - other Set[T]: The other set to compare with.
   239  //
   240  // Returns:
   241  //
   242  // - bool: true if 's' is a superset of 'other', false otherwise.
   243  //
   244  // Example usage:
   245  //
   246  //	s1 := g.SetOf(1, 2, 3, 4, 5)
   247  //	s2 := g.SetOf(1, 2, 3)
   248  //	isSuperset := s1.Superset(s2) // Returns true
   249  func (s Set[T]) Superset(other Set[T]) bool { return s.ContainsAll(other) }
   250  
   251  // Eq checks if two Sets are equal.
   252  func (s Set[T]) Eq(other Set[T]) bool {
   253  	if len(s) != len(other) {
   254  		return false
   255  	}
   256  
   257  	for v := range other {
   258  		if !s.Contains(v) {
   259  			return false
   260  		}
   261  	}
   262  
   263  	return true
   264  }
   265  
   266  // Ne checks if two Sets are not equal.
   267  func (s Set[T]) Ne(other Set[T]) bool { return !s.Eq(other) }
   268  
   269  // Clear removes all values from the Set.
   270  func (s Set[T]) Clear() Set[T] { return s.Remove(s.ToSlice()...) }
   271  
   272  // Empty checks if the Set is empty.
   273  func (s Set[T]) Empty() bool { return len(s) == 0 }
   274  
   275  // String returns a string representation of the Set.
   276  func (s Set[T]) String() string {
   277  	builder := NewBuilder()
   278  
   279  	s.Iter().ForEach(func(v T) { builder.Write(Sprintf("%v, ", v)) })
   280  
   281  	return builder.String().TrimRight(", ").Format("Set{%s}").Std()
   282  }
   283  
   284  // Print prints the elements of the Set to the standard output (console)
   285  // and returns the Set unchanged.
   286  func (s Set[T]) Print() Set[T] { fmt.Println(s); return s }