github.com/searKing/golang/go@v1.2.117/exp/maps/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 maps 6 7 // Split slices s into all submaps separated by sep and returns a slice of 8 // the submaps 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 submaps). 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[M ~map[K]V, K comparable, V any](m M, sep int) []M { 21 return SplitN(m, sep, -1) 22 } 23 24 // SplitN slices s into submaps and returns a slice of the submaps. 25 // 26 // The count determines the number of submaps to return: 27 // 28 // n > 0: at most n submaps; the last submaps will be the unsplit remainder. 29 // The count determines the number of submaps to return: 30 // sep > 0: Split splits every sep as chunk size; the last submaps will be the unsplit remainder. 31 // sep <= 0: take len(S)/n as chunk size 32 // n == 0: the result is nil (zero submaps) 33 // n < 0: all submaps 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[M ~map[K]V, K comparable, V any](m M, sep int, n int) []M { 38 // n < 0: all submaps as n == len(s) 39 if n < 0 { 40 n = len(m) 41 } 42 // Below: n >= 0 43 44 // n == 0: the result is nil (zero submaps) 45 // If s is nil, Split returns nil (zero submaps). 46 if n == 0 || m == 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(m) == 0 && sep == 0 { 54 return []M{} 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(m) <= sep && sep > 0 { 60 return []M{m} 61 } 62 63 // Below: len(s) > 0 && len(s) > sep && n > 0 64 65 // n > 0: at most n submaps; the last submaps will be the unsplit remainder. 66 // The count determines the number of submaps to return: 67 // sep > 0: Split splits every sep as chunk size; the last submaps will be the unsplit remainder. 68 // sep <= 0: take len(S)/n as chunk size 69 70 if n == 1 || len(m) == 1 { 71 return []M{m} 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(m) / n 78 if chunkSize == 0 { 79 chunkSize = 1 80 } 81 if sep > 0 { 82 chunkSize = sep 83 } 84 var chunks []M 85 var chunk = make(M) 86 for k, v := range m { 87 if len(chunks) == n-1 || chunkSize > len(m) { 88 chunkSize = len(m) 89 } 90 if len(chunk) < chunkSize { 91 chunk[k] = v 92 } 93 if len(chunk) == chunkSize { 94 chunks = append(chunks, chunk) 95 chunk = make(M) 96 } 97 } 98 if len(chunk) > 0 { 99 chunks = append(chunks, chunk) 100 } 101 return chunks 102 }