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.