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 }