bitbucket.org/ai69/amoy@v0.2.3/sequence.go (about) 1 package amoy 2 3 import ( 4 "fmt" 5 "sort" 6 "strings" 7 ) 8 9 // ParseIntSequence parses sequences like "9-12,10,20" into slices of int like [9, 10, 11, 12, 20]. 10 func ParseIntSequence(s, splitSep, rangeSep string) ([]int, error) { 11 if splitSep == rangeSep || len(splitSep) == 0 || len(rangeSep) == 0 { 12 return nil, fmt.Errorf("invalid separators") 13 } 14 var ( 15 temp []int 16 numA, numB int 17 err error 18 ) 19 parts := strings.Split(s, splitSep) 20 for _, p := range parts { 21 ns := strings.Split(p, rangeSep) 22 if len(ns) == 1 { 23 if numA, err = Atoi(ns[0]); err != nil { 24 return nil, err 25 } 26 temp = append(temp, numA) 27 } else if len(ns) == 2 { 28 if numA, err = Atoi(ns[0]); err != nil { 29 return nil, err 30 } 31 if numB, err = Atoi(ns[1]); err != nil { 32 return nil, err 33 } 34 if numA > numB { 35 return nil, fmt.Errorf("invalid range bound: %d > %d", numA, numB) 36 } 37 for i := numA; i <= numB; i++ { 38 temp = append(temp, i) 39 } 40 } else { 41 return nil, fmt.Errorf("invalid range format: %s", p) 42 } 43 } 44 result := DistinctInts(temp) 45 sort.Ints(result) 46 return result, nil 47 } 48 49 // MergeIntSequence merges int slices like [8, 8, 9, 10, 20, 12]. into sequences like "8-10,12,20". 50 func MergeIntSequence(num []int, splitSep, rangeSep string) string { 51 if len(num) == 0 { 52 return "" 53 } 54 sort.Ints(num) 55 var ( 56 result []string 57 beginNum int 58 lastNum int 59 saveRange = func(bg, lt int) { 60 if bg == lt { 61 result = append(result, fmt.Sprintf("%d", bg)) 62 } else { 63 result = append(result, fmt.Sprintf("%d%s%d", bg, rangeSep, lt)) 64 } 65 } 66 ) 67 for i, n := range num { 68 if i == 0 { 69 beginNum = n 70 } else if n != lastNum+1 && n != lastNum { 71 saveRange(beginNum, lastNum) 72 beginNum = n 73 } 74 lastNum = n 75 } 76 saveRange(beginNum, lastNum) 77 return strings.Join(result, splitSep) 78 } 79 80 // DistinctInts returns a new slice with the same order but without duplicate int elements. 81 func DistinctInts(ori []int) []int { 82 exist := make(map[int]struct{}) 83 for _, n := range ori { 84 exist[n] = struct{}{} 85 } 86 result := make([]int, 0) 87 for _, n := range ori { 88 if _, ok := exist[n]; ok { 89 result = append(result, n) 90 delete(exist, n) 91 } 92 } 93 return result 94 }