github.com/primecitizens/pcz/std@v0.2.1/builtin/slice/shrink.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright 2023 The Prime Citizens
     3  //
     4  // Copyright 2021 The Go Authors. All rights reserved.
     5  // Use of this source code is governed by a BSD-style
     6  // license that can be found in the LICENSE file.
     7  
     8  package stdslice
     9  
    10  // Compact replaces consecutive runs of equal elements with a single copy.
    11  // This is like the uniq command found on Unix.
    12  //
    13  // Compact modifies the contents of the slice s and returns the modified slice,
    14  // which may have a smaller length.
    15  // When Compact discards m elements in total, it might not modify the elements
    16  // s[len(s)-m:len(s)]. If those elements contain pointers you might consider
    17  // zeroing those elements so that objects they reference can be garbage collected.
    18  func Compact[E any](s []E, eq func(s []E, prev, cur int) bool) []E {
    19  	if len(s) < 2 {
    20  		return s
    21  	}
    22  	i := 1
    23  	for k := 1; k < len(s); k++ {
    24  		if eq(s, k-1, k) {
    25  			continue
    26  		}
    27  
    28  		if i != k {
    29  			s[i] = s[k]
    30  		}
    31  		i++
    32  	}
    33  	return s[:i]
    34  }
    35  
    36  // CompactEx is like [Compact], but takes an extra arg.
    37  func CompactEx[E, T any](s []E, arg T, eq func(arg T, s []E, prev, cur int) bool) []E {
    38  	if len(s) < 2 {
    39  		return s
    40  	}
    41  	i := 1
    42  	for k := 1; k < len(s); k++ {
    43  		if eq(arg, s, k-1, k) {
    44  			continue
    45  		}
    46  
    47  		if i != k {
    48  			s[i] = s[k]
    49  		}
    50  		i++
    51  	}
    52  	return s[:i]
    53  }
    54  
    55  // Delete removes the elements s[i:j] from s, returning the modified slice.
    56  // Delete panics if s[i:j] is not a valid slice of s.
    57  // Delete is O(len(s)-j), so if many items must be deleted, it is better to
    58  // make a single call deleting them all together than to delete one at a time.
    59  // Delete might not modify the elements s[len(s)-(j-i):len(s)]. If those
    60  // elements contain pointers you might consider zeroing those elements so that
    61  // objects they reference can be garbage collected.
    62  func Delete[E any](s []E, i, j int) []E {
    63  	_ = s[i:j] // bounds check
    64  	return append(s[:i], s[j:]...)
    65  }
    66  
    67  func Cut[E any](s []E) (used, remaining []E) {
    68  	return s[:len(s):len(s)], s[len(s):len(s):cap(s)]
    69  }