diff --git a/slice/slice.go b/slice/slice.go index 1bf06f0..e091a85 100644 --- a/slice/slice.go +++ b/slice/slice.go @@ -115,6 +115,28 @@ func Filter(slice, function interface{}) interface{} { return res.Interface() } +// Find iterates over elements of slice, returning the first one that passes a truth test on function. +// The function signature should be func(index int, value interface{}) bool . +func Find(slice, function interface{}) interface{} { + sv := sliceValue(slice) + fn := functionValue(function) + + elemType := sv.Type().Elem() + if checkSliceCallbackFuncSignature(fn, elemType, reflect.ValueOf(true).Type()) { + panic("Filter function must be of type func(int, " + elemType.String() + ")" + reflect.ValueOf(true).Type().String()) + } + + var index int + for i := 0; i < sv.Len(); i++ { + flag := fn.Call([]reflect.Value{reflect.ValueOf(i), sv.Index(i)})[0] + if flag.Bool() { + index = i + break + } + } + return sv.Index(index).Interface() +} + // Map creates an slice of values by running each element of `slice` thru `function`. // The function signature should be func(index int, value interface{}) interface{}. func Map(slice, function interface{}) interface{} { diff --git a/slice/slice_test.go b/slice/slice_test.go index 6942a70..2f020af 100644 --- a/slice/slice_test.go +++ b/slice/slice_test.go @@ -137,6 +137,18 @@ func TestFilter(t *testing.T) { } +func TestFind(t *testing.T) { + nums := []int{1, 2, 3, 4, 5} + even := func(i, num int) bool { + return num%2 == 0 + } + res := Find(nums, even) + if res != 2 { + utils.LogFailedTestInfo(t, "Find", nums, 2, res) + t.FailNow() + } +} + func TestMap(t *testing.T) { s1 := []int{1, 2, 3, 4} multiplyTwo := func(i, num int) int {