strings.go 3.8 KB

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