stringset.go (5047B)
1 /* 2 * MinIO Go Library for Amazon S3 Compatible Cloud Storage 3 * Copyright 2015-2017 MinIO, Inc. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package set 19 20 import ( 21 "fmt" 22 "sort" 23 24 jsoniter "github.com/json-iterator/go" 25 ) 26 27 // StringSet - uses map as set of strings. 28 type StringSet map[string]struct{} 29 30 var json = jsoniter.ConfigCompatibleWithStandardLibrary 31 32 // ToSlice - returns StringSet as string slice. 33 func (set StringSet) ToSlice() []string { 34 keys := make([]string, 0, len(set)) 35 for k := range set { 36 keys = append(keys, k) 37 } 38 sort.Strings(keys) 39 return keys 40 } 41 42 // IsEmpty - returns whether the set is empty or not. 43 func (set StringSet) IsEmpty() bool { 44 return len(set) == 0 45 } 46 47 // Add - adds string to the set. 48 func (set StringSet) Add(s string) { 49 set[s] = struct{}{} 50 } 51 52 // Remove - removes string in the set. It does nothing if string does not exist in the set. 53 func (set StringSet) Remove(s string) { 54 delete(set, s) 55 } 56 57 // Contains - checks if string is in the set. 58 func (set StringSet) Contains(s string) bool { 59 _, ok := set[s] 60 return ok 61 } 62 63 // FuncMatch - returns new set containing each value who passes match function. 64 // A 'matchFn' should accept element in a set as first argument and 65 // 'matchString' as second argument. The function can do any logic to 66 // compare both the arguments and should return true to accept element in 67 // a set to include in output set else the element is ignored. 68 func (set StringSet) FuncMatch(matchFn func(string, string) bool, matchString string) StringSet { 69 nset := NewStringSet() 70 for k := range set { 71 if matchFn(k, matchString) { 72 nset.Add(k) 73 } 74 } 75 return nset 76 } 77 78 // ApplyFunc - returns new set containing each value processed by 'applyFn'. 79 // A 'applyFn' should accept element in a set as a argument and return 80 // a processed string. The function can do any logic to return a processed 81 // string. 82 func (set StringSet) ApplyFunc(applyFn func(string) string) StringSet { 83 nset := NewStringSet() 84 for k := range set { 85 nset.Add(applyFn(k)) 86 } 87 return nset 88 } 89 90 // Equals - checks whether given set is equal to current set or not. 91 func (set StringSet) Equals(sset StringSet) bool { 92 // If length of set is not equal to length of given set, the 93 // set is not equal to given set. 94 if len(set) != len(sset) { 95 return false 96 } 97 98 // As both sets are equal in length, check each elements are equal. 99 for k := range set { 100 if _, ok := sset[k]; !ok { 101 return false 102 } 103 } 104 105 return true 106 } 107 108 // Intersection - returns the intersection with given set as new set. 109 func (set StringSet) Intersection(sset StringSet) StringSet { 110 nset := NewStringSet() 111 for k := range set { 112 if _, ok := sset[k]; ok { 113 nset.Add(k) 114 } 115 } 116 117 return nset 118 } 119 120 // Difference - returns the difference with given set as new set. 121 func (set StringSet) Difference(sset StringSet) StringSet { 122 nset := NewStringSet() 123 for k := range set { 124 if _, ok := sset[k]; !ok { 125 nset.Add(k) 126 } 127 } 128 129 return nset 130 } 131 132 // Union - returns the union with given set as new set. 133 func (set StringSet) Union(sset StringSet) StringSet { 134 nset := NewStringSet() 135 for k := range set { 136 nset.Add(k) 137 } 138 139 for k := range sset { 140 nset.Add(k) 141 } 142 143 return nset 144 } 145 146 // MarshalJSON - converts to JSON data. 147 func (set StringSet) MarshalJSON() ([]byte, error) { 148 return json.Marshal(set.ToSlice()) 149 } 150 151 // UnmarshalJSON - parses JSON data and creates new set with it. 152 // If 'data' contains JSON string array, the set contains each string. 153 // If 'data' contains JSON string, the set contains the string as one element. 154 // If 'data' contains Other JSON types, JSON parse error is returned. 155 func (set *StringSet) UnmarshalJSON(data []byte) error { 156 sl := []string{} 157 var err error 158 if err = json.Unmarshal(data, &sl); err == nil { 159 *set = make(StringSet) 160 for _, s := range sl { 161 set.Add(s) 162 } 163 } else { 164 var s string 165 if err = json.Unmarshal(data, &s); err == nil { 166 *set = make(StringSet) 167 set.Add(s) 168 } 169 } 170 171 return err 172 } 173 174 // String - returns printable string of the set. 175 func (set StringSet) String() string { 176 return fmt.Sprintf("%s", set.ToSlice()) 177 } 178 179 // NewStringSet - creates new string set. 180 func NewStringSet() StringSet { 181 return make(StringSet) 182 } 183 184 // CreateStringSet - creates new string set with given string values. 185 func CreateStringSet(sl ...string) StringSet { 186 set := make(StringSet) 187 for _, k := range sl { 188 set.Add(k) 189 } 190 return set 191 } 192 193 // CopyStringSet - returns copy of given set. 194 func CopyStringSet(set StringSet) StringSet { 195 nset := NewStringSet() 196 for k, v := range set { 197 nset[k] = v 198 } 199 return nset 200 }