github.com/jxskiss/gopkg@v0.17.3/set/string.go (about)

     1  // Code generated by go generate at 2021-05-30T01:20:54+08:00; DO NOT EDIT.
     2  
     3  package set
     4  
     5  import "encoding/json"
     6  
     7  // String is string set collection.
     8  // The zero value of String is an empty instance ready to use. A zero String
     9  // value shall not be copied, or it may result incorrect behavior.
    10  type String struct {
    11  	m map[string]struct{}
    12  }
    13  
    14  // NewString creates String instance.
    15  func NewString(vals ...string) String {
    16  	size := max(len(vals), minSize)
    17  	set := String{
    18  		m: make(map[string]struct{}, size),
    19  	}
    20  	set.Add(vals...)
    21  	return set
    22  }
    23  
    24  // NewStringWithSize creates String instance with given initial size.
    25  func NewStringWithSize(size int) String {
    26  	set := String{
    27  		m: make(map[string]struct{}, size),
    28  	}
    29  	return set
    30  }
    31  
    32  // Size returns the size of set.
    33  func (s String) Size() int { return len(s.m) }
    34  
    35  // Add adds values into the set.
    36  func (s *String) Add(vals ...string) {
    37  	if s.m == nil {
    38  		size := max(len(vals), minSize)
    39  		s.m = make(map[string]struct{}, size)
    40  	}
    41  	for idx := range vals {
    42  		s.m[vals[idx]] = struct{}{}
    43  	}
    44  }
    45  
    46  // Del deletes values from the set.
    47  func (s *String) Del(vals ...string) {
    48  	for idx := range vals {
    49  		delete(s.m, vals[idx])
    50  	}
    51  }
    52  
    53  // Pop pops an element from the set, in no particular order.
    54  func (s *String) Pop() string {
    55  	for val := range s.m {
    56  		delete(s.m, val)
    57  		return val
    58  	}
    59  	return ""
    60  }
    61  
    62  // Iterate iterates the set in no particular order and call the given function
    63  // for each set element.
    64  func (s String) Iterate(fn func(string)) {
    65  	for val := range s.m {
    66  		fn(val)
    67  	}
    68  }
    69  
    70  // Contains returns true if the set contains all the values.
    71  func (s String) Contains(vals ...string) bool {
    72  	if len(vals) == 0 {
    73  		return false
    74  	}
    75  	for _, v := range vals {
    76  		if _, ok := s.m[v]; !ok {
    77  			return false
    78  		}
    79  	}
    80  	return true
    81  }
    82  
    83  // ContainsAny returns true if the set contains any of the values.
    84  func (s String) ContainsAny(vals ...string) bool {
    85  	for _, v := range vals {
    86  		if _, ok := s.m[v]; ok {
    87  			return true
    88  		}
    89  	}
    90  	return false
    91  }
    92  
    93  // Diff returns new String about the values which other set doesn't contain.
    94  func (s String) Diff(other String) String {
    95  	res := NewStringWithSize(s.Size())
    96  
    97  	for val := range s.m {
    98  		if _, ok := other.m[val]; !ok {
    99  			res.m[val] = struct{}{}
   100  		}
   101  	}
   102  	return res
   103  }
   104  
   105  // DiffSlice is similar to Diff, but takes a slice as parameter.
   106  func (s String) DiffSlice(other []string) String {
   107  	if len(s.m) > len(other) {
   108  		tmp := NewStringWithSize(len(other))
   109  		dup := 0
   110  		for _, val := range other {
   111  			if _, ok := s.m[val]; ok {
   112  				dup++
   113  			}
   114  			tmp.m[val] = struct{}{}
   115  		}
   116  		res := NewStringWithSize(max(s.Size()-dup, 0))
   117  		for val := range s.m {
   118  			if _, ok := tmp.m[val]; !ok {
   119  				res.m[val] = struct{}{}
   120  			}
   121  		}
   122  		return res
   123  	} else {
   124  		res := NewStringWithSize(s.Size())
   125  		for val := range s.m {
   126  			res.m[val] = struct{}{}
   127  		}
   128  		for _, val := range other {
   129  			if _, ok := res.m[val]; ok {
   130  				delete(res.m, val)
   131  			}
   132  		}
   133  		return res
   134  	}
   135  }
   136  
   137  // FilterInclude returns a new slice which contains values that present in
   138  // the provided slice and also present in the String set.
   139  func (s String) FilterInclude(slice []string) []string {
   140  	res := make([]string, 0, min(s.Size(), len(slice)))
   141  	for _, val := range slice {
   142  		if _, ok := s.m[val]; ok {
   143  			res = append(res, val)
   144  		}
   145  	}
   146  	return res
   147  }
   148  
   149  // FilterExclude returns a new slice which contains values that present in
   150  // the provided slice but don't present in the String set.
   151  func (s String) FilterExclude(slice []string) []string {
   152  	res := make([]string, 0, len(slice))
   153  	for _, val := range slice {
   154  		if _, ok := s.m[val]; !ok {
   155  			res = append(res, val)
   156  		}
   157  	}
   158  	return res
   159  }
   160  
   161  // Intersect returns new String about values which other set also contains.
   162  func (s String) Intersect(other String) String {
   163  	res := NewStringWithSize(min(s.Size(), other.Size()))
   164  
   165  	// loop over the smaller set
   166  	if len(s.m) <= len(other.m) {
   167  		for val := range s.m {
   168  			if _, ok := other.m[val]; ok {
   169  				res.m[val] = struct{}{}
   170  			}
   171  		}
   172  	} else {
   173  		for val := range other.m {
   174  			if _, ok := s.m[val]; ok {
   175  				res.m[val] = struct{}{}
   176  			}
   177  		}
   178  	}
   179  	return res
   180  }
   181  
   182  // IntersectSlice is similar to Intersect, but takes a slice as parameter.
   183  func (s String) IntersectSlice(other []string) String {
   184  	res := NewStringWithSize(min(s.Size(), len(other)))
   185  
   186  	for _, val := range other {
   187  		if _, ok := s.m[val]; ok {
   188  			res.m[val] = struct{}{}
   189  		}
   190  	}
   191  	return res
   192  }
   193  
   194  // Union returns new String about values either in the set or the other set.
   195  func (s String) Union(other String) String {
   196  	res := NewStringWithSize(s.Size() + other.Size())
   197  
   198  	for val := range s.m {
   199  		res.m[val] = struct{}{}
   200  	}
   201  	for val := range other.m {
   202  		res.m[val] = struct{}{}
   203  	}
   204  	return res
   205  }
   206  
   207  // UnionSlice is similar to Union, but takes a slice as parameter.
   208  func (s String) UnionSlice(other []string) String {
   209  	res := NewStringWithSize(s.Size() + len(other))
   210  
   211  	for val := range s.m {
   212  		res.m[val] = struct{}{}
   213  	}
   214  	for _, val := range other {
   215  		res.m[val] = struct{}{}
   216  	}
   217  	return res
   218  }
   219  
   220  // Slice converts set into string slice.
   221  func (s String) Slice() []string {
   222  	res := make([]string, 0, len(s.m))
   223  
   224  	for val := range s.m {
   225  		res = append(res, val)
   226  	}
   227  	return res
   228  }
   229  
   230  // Map converts set into map[string]bool.
   231  func (s String) Map() map[string]bool {
   232  	res := make(map[string]bool, len(s.m))
   233  
   234  	for val := range s.m {
   235  		res[val] = true
   236  	}
   237  	return res
   238  }
   239  
   240  // MarshalJSON implements json.Marshaler interface, the set will be
   241  // marshaled as an string array.
   242  func (s String) MarshalJSON() ([]byte, error) {
   243  	res := s.Slice()
   244  	return json.Marshal(res)
   245  }
   246  
   247  // UnmarshalJSON implements json.Unmarshaler interface, it will unmarshal
   248  // an string array to the set.
   249  func (s *String) UnmarshalJSON(b []byte) error {
   250  	vals := make([]string, 0)
   251  	err := json.Unmarshal(b, &vals)
   252  	if err == nil {
   253  		s.Add(vals...)
   254  	}
   255  	return err
   256  }
   257  
   258  // MarshalYAML implements yaml.Marshaler interface of the yaml package,
   259  // the set will be marshaled as an string array.
   260  func (s String) MarshalYAML() (interface{}, error) {
   261  	res := s.Slice()
   262  	return res, nil
   263  }
   264  
   265  // UnmarshalYAML implements yaml.Unmarshaler interface of the yaml package,
   266  // it will unmarshal an string array to the set.
   267  func (s *String) UnmarshalYAML(unmarshal func(interface{}) error) error {
   268  	vals := make([]string, 0)
   269  	err := unmarshal(&vals)
   270  	if err == nil {
   271  		s.Add(vals...)
   272  	}
   273  	return err
   274  }