github.com/searKing/golang/go@v1.2.117/exp/slices/spilt.go (about) 1 // Copyright 2022 The searKing Author. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package slices 6 7 // Split slices s into all subslices separated by sep and returns a slice of 8 // the subslices between those separators. 9 // 10 // If s is less than sep and sep is more than zero, Split returns a 11 // slice of length 1 whose only element is s. 12 // 13 // If s is nil, Split returns nil (zero subslices). 14 // 15 // If both s and sep are empty or zero, Split returns an empty slice. 16 // 17 // If sep is <= zero, Split splits after each element, as chunk size is 1. 18 // 19 // It is equivalent to SplitN with a count of -1. 20 func Split[S ~[]E, E any](s S, sep int) []S { 21 return SplitN(s, sep, -1) 22 } 23 24 // SplitN slices s into subslices and returns a slice of the subslices. 25 // 26 // The count determines the number of subslices to return: 27 // 28 // n > 0: at most n subslices; the last subslices will be the unsplit remainder. 29 // The count determines the number of subslices to return: 30 // sep > 0: Split splits every sep as chunk size; the last subslices will be the unsplit remainder. 31 // sep <= 0: take len(S)/n as chunk size 32 // n == 0: the result is nil (zero subslices) 33 // n < 0: all subslices as n == len(s) 34 // 35 // Edge cases for s and sep (for example, zero) are handled 36 // as described in the documentation for Split. 37 func SplitN[S ~[]E, E any](s S, sep int, n int) []S { 38 // n < 0: all subslices as n == len(s) 39 if n < 0 { 40 n = len(s) 41 } 42 // Below: n >= 0 43 44 // n == 0: the result is nil (zero subslices) 45 // If s is nil, Split returns nil (zero subslices). 46 if n == 0 || s == nil { 47 return nil 48 } 49 50 // Below: s != nil && n > 0 51 52 // If both s and sep are empty or zero, Split returns an empty slice. 53 if len(s) == 0 && sep == 0 { 54 return []S{} 55 } 56 57 // If s is less or equal than sep and sep is more than zero, Split returns a 58 // slice of length 1 whose only element is s. 59 if len(s) <= sep && sep > 0 { 60 return []S{s} 61 } 62 63 // Below: len(s) > 0 && len(s) > sep && n > 0 64 65 // n > 0: at most n subslices; the last subslices will be the unsplit remainder. 66 // The count determines the number of subslices to return: 67 // sep > 0: Split splits every sep as chunk size; the last subslices will be the unsplit remainder. 68 // sep <= 0: take len(S)/n as chunk size 69 70 if n == 1 || len(s) == 1 { 71 return []S{s} 72 } 73 74 // Below: len(s) > 1 && len(s) > sep && n > 1 75 76 // If sep is <= zero, Split splits after each element, as chunk size is 1. 77 chunkSize := len(s) / n 78 if chunkSize == 0 { 79 chunkSize = 1 80 } 81 if sep > 0 { 82 chunkSize = sep 83 } 84 var chunks []S 85 for len(s) > 0 { 86 if len(chunks) == n-1 || chunkSize > len(s) { 87 chunkSize = len(s) 88 } 89 chunk := append([]E{}, s[:chunkSize]...) 90 s = s[chunkSize:] 91 chunks = append(chunks, S(chunk)) 92 } 93 return chunks 94 } 95 96 // SplitMap slices s into all key-value pairs and returns a map of the key-value pairs. 97 // 98 // If s is nil, SplitMap returns nil (zero map). 99 // 100 // If len(s) is odd, it treats args[len(args)-1] as a value with a missing value. 101 func SplitMap[M ~map[K]V, S ~[]E, K comparable, V any, E any](s S) M { 102 if s == nil { 103 return nil 104 } 105 kvs := Split(s, 2) 106 var m = make(M, len(kvs)) 107 for _, kv := range kvs { 108 switch len(kv) { 109 case 1: 110 var zeroV V 111 m[any(kv[0]).(K)] = zeroV 112 case 2: 113 m[any(kv[0]).(K)] = any(kv[1]).(V) 114 default: 115 } 116 } 117 return m 118 }