strings.go 3.5 KB

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