123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 |
- package helper
- import (
- "encoding/binary"
- "math/rand"
- "net"
- "os"
- "reflect"
- "strconv"
- "strings"
- "time"
- )
- //LowerFirst Make a string's first character lowercase
- func LowerFirst(s string) string {
- isFirst := true
- return strings.Map(func(r rune) rune {
- if isFirst && r >= 'A' && r <= 'Z' {
- r = r + 32
- }
- isFirst = false
- return r
- }, s)
- }
- //UpperFirst Make a string's first character uppercase
- func UpperFirst(s string) string {
- isFirst := true
- return strings.Map(func(r rune) rune {
- if isFirst && r >= 'a' && r <= 'z' {
- r = r - 32
- }
- isFirst = false
- return r
- }, s)
- }
- //InArray Checks if a value exists in an array
- func InArray(needle interface{}, haystack interface{}) bool {
- val := reflect.ValueOf(haystack)
- switch val.Kind() {
- case reflect.Slice, reflect.Array:
- for i := 0; i < val.Len(); i++ {
- if reflect.DeepEqual(needle, val.Index(i).Interface()) {
- return true
- }
- }
- case reflect.Map:
- for _, k := range val.MapKeys() {
- if reflect.DeepEqual(needle, val.MapIndex(k).Interface()) {
- return true
- }
- }
- default:
- panic("haystack: haystack type muset be slice, array or map")
- }
- return false
- }
- //IsEmpty Determine whether a variable is empty
- func IsEmpty(val interface{}) bool {
- if val == nil {
- return true
- }
- v := reflect.ValueOf(val)
- switch v.Kind() {
- case reflect.String, reflect.Array:
- return v.Len() == 0
- case reflect.Map, reflect.Slice:
- return v.Len() == 0 || v.IsNil()
- case reflect.Bool:
- return !v.Bool()
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return v.Int() == 0
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- return v.Uint() == 0
- case reflect.Float32, reflect.Float64:
- return v.Float() == 0
- case reflect.Interface, reflect.Ptr:
- return v.IsNil()
- }
- return reflect.DeepEqual(val, reflect.Zero(v.Type()).Interface())
- }
- //IsNumeric Finds whether a variable is a number or a numeric string
- func IsNumeric(val interface{}) bool {
- switch val.(type) {
- case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
- return true
- case float32, float64, complex64, complex128:
- return true
- case string:
- str := val.(string)
- if str == "" {
- return false
- }
- // Trim any whitespace
- str = strings.TrimSpace(str)
- if str[0] == '-' || str[0] == '+' {
- if len(str) == 1 {
- return false
- }
- str = str[1:]
- }
- // hex
- if len(str) > 2 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X') {
- for _, h := range str[2:] {
- if !((h >= '0' && h <= '9') || (h >= 'a' && h <= 'f') || (h >= 'A' && h <= 'F')) {
- return false
- }
- }
- return true
- }
- // 0-9, Point, Scientific
- p, s, l := 0, 0, len(str)
- for i, v := range str {
- if v == '.' { // Point
- if p > 0 || s > 0 || i+1 == l {
- return false
- }
- p = i
- } else if v == 'e' || v == 'E' { // Scientific
- if i == 0 || s > 0 || i+1 == l {
- return false
- }
- s = i
- } else if v < '0' || v > '9' {
- return false
- }
- }
- return true
- }
- return false
- }
- //BreakUp break strings
- func BreakUp(s string) []string {
- length := len(s)
- b := make([]byte, length)
- ss := make([]string, 0)
- var p int
- for i := 0; i < length; i++ {
- if s[i] >= 'A' && s[i] <= 'Z' {
- if p > 0 {
- ss = append(ss, string(b[:p]))
- }
- p = 0
- b[p] = s[i] + 32
- } else {
- b[p] = s[i]
- }
- p++
- }
- if p > 0 {
- ss = append(ss, string(b[:p]))
- }
- return ss
- }
- //Camel2id eg SendMail into send-mail
- func Camel2id(s string) string {
- return strings.Join(BreakUp(s), "-")
- }
- //Rand Generate a random integer
- func Rand(min, max int) int {
- if min > max {
- panic("min: min cannot be greater than max")
- }
- if int31 := 1<<31 - 1; max > int31 {
- panic("max: max can not be greater than " + strconv.Itoa(int31))
- }
- if min == max {
- return min
- }
- r := rand.New(rand.NewSource(time.Now().UnixNano()))
- return r.Intn(max+1-min) + min
- }
- //FileExists Checks whether a file or directory exists
- func FileExists(filename string) bool {
- if _, err := os.Stat(filename); err != nil && os.IsNotExist(err) {
- return false
- }
- return true
- }
- //IsDir Tells whether the filename is a directory
- func IsDir(filename string) (bool, error) {
- fd, err := os.Stat(filename)
- if err != nil {
- return false, err
- }
- fm := fd.Mode()
- return fm.IsDir(), nil
- }
- //SimilarText Calculate the similarity between two strings
- func SimilarText(first, second string, percent *float64) int {
- var similarText func(string, string, int, int) int
- similarText = func(str1, str2 string, len1, len2 int) int {
- var sum, max int
- pos1, pos2 := 0, 0
- // Find the longest segment of the same section in two strings
- for i := 0; i < len1; i++ {
- for j := 0; j < len2; j++ {
- for l := 0; (i+l < len1) && (j+l < len2) && (str1[i+l] == str2[j+l]); l++ {
- if l+1 > max {
- max = l + 1
- pos1 = i
- pos2 = j
- }
- }
- }
- }
- if sum = max; sum > 0 {
- if pos1 > 0 && pos2 > 0 {
- sum += similarText(str1, str2, pos1, pos2)
- }
- if (pos1+max < len1) && (pos2+max < len2) {
- s1 := []byte(str1)
- s2 := []byte(str2)
- sum += similarText(string(s1[pos1+max:]), string(s2[pos2+max:]), len1-pos1-max, len2-pos2-max)
- }
- }
- return sum
- }
- l1, l2 := len(first), len(second)
- if l1+l2 == 0 {
- return 0
- }
- sim := similarText(first, second, l1, l2)
- if percent != nil {
- *percent = float64(sim*200) / float64(l1+l2)
- }
- return sim
- }
- //IP2long Converts a string containing an (IPv4) Internet Protocol dotted address into a long integer
- func IP2long(ipAddress string) uint32 {
- ip := net.ParseIP(ipAddress)
- if ip == nil {
- return 0
- }
- return binary.BigEndian.Uint32(ip.To4())
- }
- //Long2IP Converts an long integer address into a string in (IPv4) Internet standard dotted format
- func Long2IP(properAddress uint32) string {
- ipByte := make([]byte, 4)
- binary.BigEndian.PutUint32(ipByte, properAddress)
- ip := net.IP(ipByte)
- return ip.String()
- }
|