From 1ad990ce9d88f3e94f9129902968feec9c564da1 Mon Sep 17 00:00:00 2001 From: dudaodong Date: Mon, 24 Jan 2022 15:28:47 +0800 Subject: [PATCH] feat: add FindLast func --- slice/slice.go | 28 ++++++++++++++++++++++++++++ slice/slice_test.go | 16 +++++++++++++++- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/slice/slice.go b/slice/slice.go index 9f0b7fb..b8ada2f 100644 --- a/slice/slice.go +++ b/slice/slice.go @@ -367,6 +367,34 @@ func Find(slice, function interface{}) (interface{}, bool) { return sv.Index(index).Interface(), true } +// FindLast iterates over elements of slice from end to begin, returning the first one that passes a truth test on function. +// The function signature should be func(index int, value interface{}) bool . +func FindLast(slice, function interface{}) (interface{}, bool) { + sv := sliceValue(slice) + fn := functionValue(function) + + elemType := sv.Type().Elem() + if checkSliceCallbackFuncSignature(fn, elemType, reflect.ValueOf(true).Type()) { + panic("function param should be of type func(int, " + elemType.String() + ")" + reflect.ValueOf(true).Type().String()) + } + + index := -1 + for i := sv.Len() - 1; i >= 0; i-- { + flag := fn.Call([]reflect.Value{reflect.ValueOf(i), sv.Index(i)})[0] + if flag.Bool() { + index = i + break + } + } + + if index == -1 { + var none interface{} + return none, false + } + + return sv.Index(index).Interface(), true +} + // FlattenDeep flattens slice recursive func FlattenDeep(slice interface{}) interface{} { sv := sliceValue(slice) diff --git a/slice/slice_test.go b/slice/slice_test.go index eec492d..3463ced 100644 --- a/slice/slice_test.go +++ b/slice/slice_test.go @@ -172,6 +172,20 @@ func TestFind(t *testing.T) { assert.Equal(2, res) } +func TestFindLast(t *testing.T) { + nums := []int{1, 2, 3, 4, 5} + even := func(i, num int) bool { + return num%2 == 0 + } + res, ok := FindLast(nums, even) + if !ok { + t.Fatal("found nothing") + } + + assert := internal.NewAssert(t, "TestFind") + assert.Equal(4, res) +} + func TestFindFoundNothing(t *testing.T) { nums := []int{1, 1, 1, 1, 1, 1} findFunc := func(i, num int) bool { @@ -443,7 +457,7 @@ func TestDifferenceBy(t *testing.T) { assert := internal.NewAssert(t, "TestDifferenceBy") s1 := []int{1, 2, 3, 4, 5} //after add one: 2 3 4 5 6 - s2 := []int{3, 4, 5} //after add one: 4 5 6 + s2 := []int{3, 4, 5} //after add one: 4 5 6 addOne := func(i int, v int) int { return v + 1 }