From 67dfc10c2e0614288f120d0fdd790754b5f0dc2b Mon Sep 17 00:00:00 2001 From: Dean Karn Date: Mon, 29 Jan 2024 10:40:35 -0800 Subject: [PATCH] Retain & Filter refactor (#46) `sliceext.Retain` & `sliceext.Filter` to not shuffle data in the underlying slice array but create new slice referencing the data instead. In practice, it can cause unexpected behaviour and users expectations not met when the same data is also referenced elsewhere. If anyone still requires a `shuffle` implementation for efficiency I'd be happy to add a separate function for that as well. --- CHANGELOG.md | 4 ++++ README.md | 2 +- slice/slice.go | 23 ++++++++++++----------- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5affeac..8476b67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [5.27.0] - 2024-01-29 +### Changed +- `sliceext.Retain` & `sliceext.Filter` to not shuffle data in the underlying slice array but create new slice referencing the data instead. In practice, it can cause unexpected behaviour and users expectations not met when the same data is also referenced elsewhere. If anyone still requires a `shuffle` implementation for efficiency I'd be happy to add a separate function for that as well. + ## [5.26.0] - 2024-01-28 ### Added - `stringsext.Join` a more ergonomic way to join strings with a separator when you don't have a slice of strings. diff --git a/README.md b/README.md index a4273be..d0fd8e3 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # pkg -![Project status](https://img.shields.io/badge/version-5.26.0-green.svg) +![Project status](https://img.shields.io/badge/version-5.27.0-green.svg) [![Lint & Test](https://github.com/go-playground/pkg/actions/workflows/go.yml/badge.svg)](https://github.com/go-playground/pkg/actions/workflows/go.yml) [![Coverage Status](https://coveralls.io/repos/github/go-playground/pkg/badge.svg?branch=master)](https://coveralls.io/github/go-playground/pkg?branch=master) [![GoDoc](https://godoc.org/github.com/go-playground/pkg?status.svg)](https://pkg.go.dev/mod/github.com/go-playground/pkg/v5) diff --git a/slice/slice.go b/slice/slice.go index 8c15326..50c9f53 100644 --- a/slice/slice.go +++ b/slice/slice.go @@ -4,37 +4,38 @@ package sliceext import ( - optionext "github.com/go-playground/pkg/v5/values/option" "sort" + + optionext "github.com/go-playground/pkg/v5/values/option" ) // Retain retains only the elements specified by the function. // -// This shuffles and returns the retained values of the slice. +// This returns a new slice with references to the underlying data instead of shuffling. func Retain[T any](slice []T, fn func(v T) bool) []T { - var j int + results := make([]T, 0, len(slice)) for _, v := range slice { + v := v if fn(v) { - slice[j] = v - j++ + results = append(results, v) } } - return slice[:j] + return results } // Filter filters out the elements specified by the function. // -// This shuffles and returns the retained values of the slice. +// This returns a new slice with references to the underlying data instead of shuffling. func Filter[T any](slice []T, fn func(v T) bool) []T { - var j int + results := make([]T, 0, len(slice)) for _, v := range slice { + v := v if fn(v) { continue } - slice[j] = v - j++ + results = append(results, v) } - return slice[:j] + return results } // Map maps a slice of []T -> []U using the map function.