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  }