From e797d2b7764110ef1af776940250437c2a7930e4 Mon Sep 17 00:00:00 2001 From: Azimjon Pulatov Date: Sun, 25 Oct 2020 12:10:02 +0100 Subject: [PATCH] Add MinSliceIndex/MaxSliceIndex --- README.md | 16 +++++++++++++ slice.go | 35 ++++++++++++++++++++++++++++ slice_test.go | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 114 insertions(+) create mode 100644 slice.go create mode 100644 slice_test.go diff --git a/README.md b/README.md index 39d424d..34e23a8 100644 --- a/README.md +++ b/README.md @@ -137,6 +137,14 @@ MaxN returns the largest int in the set provided. If no values are provided, Max returns 0. +## func MaxSliceIndex +``` go +func MaxSliceIndex(slice interface{}, less func(i, j int) bool) int +``` +MaxSliceIndex returns the largest element index in the slice. +If slice is empty, MaxSliceIndex returns -1 + + ## func MaxUint ``` go func MaxUint(a, b uint) uint @@ -316,6 +324,14 @@ MinN returns the smallest int in the set provided. If no values are provided, Min returns 0. +## func MinSliceIndex +``` go +func MinSliceIndex(slice interface{}, less func(i, j int) bool) int +``` +MinSliceIndex returns the smallest element index in the slice. +If slice is empty, MinSliceIndex returns -1 + + ## func MinUint ``` go func MinUint(a, b uint) uint diff --git a/slice.go b/slice.go new file mode 100644 index 0000000..c43d324 --- /dev/null +++ b/slice.go @@ -0,0 +1,35 @@ +package math + +import "reflect" + +// MinSliceIndex returns the smallest element index in the slice. +// If slice is empty, MinSliceIndex returns -1 +func MinSliceIndex(slice interface{}, less func(i, j int) bool) int { + v := reflect.ValueOf(slice) + if v.Len() == 0 { + return -1 + } + minIndex := 0 + for i := 1; i < v.Len(); i++ { + if less(i, minIndex) { + minIndex = i + } + } + return minIndex +} + +// MaxSliceIndex returns the largest element index in the slice. +// If slice is empty, MaxSliceIndex returns -1 +func MaxSliceIndex(slice interface{}, less func(i, j int) bool) int { + v := reflect.ValueOf(slice) + if v.Len() == 0 { + return -1 + } + maxIndex := 0 + for i := 1; i < v.Len(); i++ { + if less(maxIndex, i) { + maxIndex = i + } + } + return maxIndex +} diff --git a/slice_test.go b/slice_test.go new file mode 100644 index 0000000..8d230a9 --- /dev/null +++ b/slice_test.go @@ -0,0 +1,63 @@ +package math + +import ( + "testing" +) + +var minSliceIndexTests = []struct { + v []struct{ n int } + want int +}{ + { + v: []struct{ n int }{{1}}, + want: 0, + }, + { + v: []struct{ n int }{{7}, {2}}, + want: 1, + }, + { + v: []struct{ n int }{{12}, {18}, {17}, {9}}, + want: 3, + }, +} + +func TestMinSliceIndex(t *testing.T) { + for i, tt := range minSliceIndexTests { + got := MinSliceIndex(tt.v, func(i, j int) bool { + return tt.v[i].n < tt.v[j].n + }) + if tt.want != got { + t.Errorf("%d: MinSliceIndex(%v) = %v, want %v", i+1, tt.v, got, tt.want) + } + } +} + +var maxSliceIndexTests = []struct { + v []struct{ n int } + want int +}{ + { + v: []struct{ n int }{{1}}, + want: 0, + }, + { + v: []struct{ n int }{{7}, {2}}, + want: 0, + }, + { + v: []struct{ n int }{{12}, {18}, {17}, {19}}, + want: 3, + }, +} + +func TestMaxSliceIndex(t *testing.T) { + for i, tt := range maxSliceIndexTests { + got := MaxSliceIndex(tt.v, func(i, j int) bool { + return tt.v[i].n < tt.v[j].n + }) + if tt.want != got { + t.Errorf("%d: MaxSliceIndex(%v) = %v, want %v", i+1, tt.v, got, tt.want) + } + } +}