From e0b241fab05f37ca898d595bdd98a1645cc5c2ff Mon Sep 17 00:00:00 2001 From: Mariusz Gronczewski Date: Wed, 3 May 2023 22:34:02 +0200 Subject: [PATCH] SliceReverse, SliceReverseInplace --- README.md | 2 ++ slice.go | 22 +++++++++++++++++++--- slice_test.go | 13 +++++++++++++ 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6a2db1a..f49e380 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,8 @@ fmt.Printf("%+v", mappedData) * `SliceIn` - Check whether value is in slice * `SliceDedupe` - remove duplicates from `comparable` slice. `[]T -> []T` * `SliceDedupeFunc` - remove duplicates from `any` slice via conversion function. `[]T -> []T` +* `SliceReverse` - reverses the order of elements in slice and returns reversed copy, `[]T -> []T` +* `SliceReverseInplace` - reverses the order of elements in slice in-place. * `FirstOrEmpty` - return first element or empty value. `[]T -> T` * `LastOrEmpty` - return last element or empty value. `[]T -> T` * `FirstOrEmpty` - return first element or passed "default" value. `[]T -> T` diff --git a/slice.go b/slice.go index 7830367..bad5798 100644 --- a/slice.go +++ b/slice.go @@ -102,7 +102,7 @@ func SliceDiff[T comparable](v1 []T, v2 []T) (inLeft []T, inRight []T) { // returns slice of elements that are only in first/left element // and ones that are only in right element. // Duplicates are ignored. -//([]DataT,[]ReturnT) -> (leftOnly []DataT, rightOnly []ReturnT) +// ([]DataT,[]ReturnT) -> (leftOnly []DataT, rightOnly []ReturnT) func SliceDiffFunc[T1 any, T2 any, Z comparable]( v1 []T1, v2 []T2, @@ -143,7 +143,7 @@ func SliceIn[T comparable](slice []T, contains T) bool { return false } -//SliceDedupe removes duplicates +// SliceDedupe removes duplicates func SliceDedupe[T comparable](slice []T) (out []T) { presence := make(map[T]bool, 0) for _, v := range slice { @@ -155,7 +155,7 @@ func SliceDedupe[T comparable](slice []T) (out []T) { return out } -//SliceDedupeFunc removes duplicates with function to convert the value to comparable +// SliceDedupeFunc removes duplicates with function to convert the value to comparable func SliceDedupeFunc[T any, C comparable](slice []T, convert func(T) C) (out []T) { presence := make(map[C]bool, 0) for _, v := range slice { @@ -168,6 +168,22 @@ func SliceDedupeFunc[T any, C comparable](slice []T, convert func(T) C) (out []T return out } +func SliceReverse[T any](in []T) (out []T) { + out = make([]T, len(in)) + copy(out, in) + for i := len(out)/2 - 1; i >= 0; i-- { + tmp := len(out) - 1 - i + out[i], out[tmp] = out[tmp], out[i] + } + return out +} +func SliceReverseInplace[T any](out []T) { + for i := len(out)/2 - 1; i >= 0; i-- { + tmp := len(out) - 1 - i + out[i], out[tmp] = out[tmp], out[i] + } +} + // FirstOrEmpty returns first element of slice or empty/default type func FirstOrEmpty[T any](slice []T) (out T) { if len(slice) > 0 { diff --git a/slice_test.go b/slice_test.go index e9584c1..3c6e6db 100644 --- a/slice_test.go +++ b/slice_test.go @@ -258,6 +258,19 @@ func TestSliceDedupeFunc(t *testing.T) { )) } +func TestSliceReverse(t *testing.T) { + a := []int{1, 9, 4, 3, 7} + b := SliceReverse(a) + assert.Equal(t, []int{7, 3, 4, 9, 1}, SliceReverse(a)) + assert.NotEqual(t, a, b) +} + +func TestSliceReverseInplace(t *testing.T) { + a := []int{1, 9, 4, 3, 7} + SliceReverseInplace(a) + assert.Equal(t, []int{7, 3, 4, 9, 1}, a) +} + func TestFirstOrEmpty(t *testing.T) { assert.Equal(t, 4, FirstOrEmpty([]int{4, 3, 2})) assert.Equal(t, 0, FirstOrEmpty([]int{}))