github.com/lingyao2333/mo-zero@v1.4.1/core/stringx/strings.go (about) 1 package stringx 2 3 import ( 4 "errors" 5 6 "github.com/lingyao2333/mo-zero/core/lang" 7 ) 8 9 var ( 10 // ErrInvalidStartPosition is an error that indicates the start position is invalid. 11 ErrInvalidStartPosition = errors.New("start position is invalid") 12 // ErrInvalidStopPosition is an error that indicates the stop position is invalid. 13 ErrInvalidStopPosition = errors.New("stop position is invalid") 14 ) 15 16 // Contains checks if str is in list. 17 func Contains(list []string, str string) bool { 18 for _, each := range list { 19 if each == str { 20 return true 21 } 22 } 23 24 return false 25 } 26 27 // Filter filters chars from s with given filter function. 28 func Filter(s string, filter func(r rune) bool) string { 29 var n int 30 chars := []rune(s) 31 for i, x := range chars { 32 if n < i { 33 chars[n] = x 34 } 35 if !filter(x) { 36 n++ 37 } 38 } 39 40 return string(chars[:n]) 41 } 42 43 // FirstN returns first n runes from s. 44 func FirstN(s string, n int, ellipsis ...string) string { 45 var i int 46 47 for j := range s { 48 if i == n { 49 ret := s[:j] 50 for _, each := range ellipsis { 51 ret += each 52 } 53 return ret 54 } 55 i++ 56 } 57 58 return s 59 } 60 61 // HasEmpty checks if there are empty strings in args. 62 func HasEmpty(args ...string) bool { 63 for _, arg := range args { 64 if len(arg) == 0 { 65 return true 66 } 67 } 68 69 return false 70 } 71 72 // NotEmpty checks if all strings are not empty in args. 73 func NotEmpty(args ...string) bool { 74 return !HasEmpty(args...) 75 } 76 77 // Remove removes given strs from strings. 78 func Remove(strings []string, strs ...string) []string { 79 out := append([]string(nil), strings...) 80 81 for _, str := range strs { 82 var n int 83 for _, v := range out { 84 if v != str { 85 out[n] = v 86 n++ 87 } 88 } 89 out = out[:n] 90 } 91 92 return out 93 } 94 95 // Reverse reverses s. 96 func Reverse(s string) string { 97 runes := []rune(s) 98 99 for from, to := 0, len(runes)-1; from < to; from, to = from+1, to-1 { 100 runes[from], runes[to] = runes[to], runes[from] 101 } 102 103 return string(runes) 104 } 105 106 // Substr returns runes between start and stop [start, stop) 107 // regardless of the chars are ascii or utf8. 108 func Substr(str string, start, stop int) (string, error) { 109 rs := []rune(str) 110 length := len(rs) 111 112 if start < 0 || start > length { 113 return "", ErrInvalidStartPosition 114 } 115 116 if stop < 0 || stop > length { 117 return "", ErrInvalidStopPosition 118 } 119 120 return string(rs[start:stop]), nil 121 } 122 123 // TakeOne returns valid string if not empty or later one. 124 func TakeOne(valid, or string) string { 125 if len(valid) > 0 { 126 return valid 127 } 128 129 return or 130 } 131 132 // TakeWithPriority returns the first not empty result from fns. 133 func TakeWithPriority(fns ...func() string) string { 134 for _, fn := range fns { 135 val := fn() 136 if len(val) > 0 { 137 return val 138 } 139 } 140 141 return "" 142 } 143 144 // Union merges the strings in first and second. 145 func Union(first, second []string) []string { 146 set := make(map[string]lang.PlaceholderType) 147 148 for _, each := range first { 149 set[each] = lang.Placeholder 150 } 151 for _, each := range second { 152 set[each] = lang.Placeholder 153 } 154 155 merged := make([]string, 0, len(set)) 156 for k := range set { 157 merged = append(merged, k) 158 } 159 160 return merged 161 }