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  }