From 4eaa0a39d51a681fbc01992e093bf8079be5af1b Mon Sep 17 00:00:00 2001 From: dudaodong Date: Mon, 24 Jan 2022 15:22:43 +0800 Subject: [PATCH] feat: add FindLast func --- README.md | 2 ++ README_zh-CN.md | 6 ++++-- slice/slice.go | 34 ++++++++++++++++++++++++++++++---- slice/slice_test.go | 14 ++++++++++++++ 4 files changed, 50 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 389ab4b..2bf7fd7 100644 --- a/README.md +++ b/README.md @@ -439,12 +439,14 @@ func Compact[T any](slice []T) []T //creates an slice with all falsey values rem func Concat[T any](slice []T, values ...[]T) []T //creates a new slice concatenating slice with any additional slices and/or values func Difference[T comparable](slice1, slice2 []T) []T //creates an slice of whose element not included in the other given slice func DifferenceBy[T any](slice []T, comparedSlice []T, iteratee func(index int, t T) T) []T //it accepts iteratee which is invoked for each element of slice and values to generate the criterion by which they're compared. +func DifferenceWith[T any](slice []T, comparedSlice []T, comparator func(value, otherValue T) bool) []T //accepts comparator which is invoked to compare elements of slice to values. The order and references of result values are determined by the first slice. func DeleteByIndex[T any](slice []T, start int, end ...int) []T //delete the element of slice from start index to end index - 1 func Drop[T any](slice []T, n int) []T //creates a slice with `n` elements dropped from the beginning when n > 0, or `n` elements dropped from the ending when n < 0 func Every[T any](slice []T, predicate func(index int, t T) bool) bool //return true if all of the values in the slice pass the predicate function func None[T any](slice []T, predicate func(index int, t T) bool) bool // return true if all the values in the slice mismatch the criteria func Filter [T any] (slice []T, predicate func(index int, t T) bool) []T //iterates over elements of slice, returning an slice of all elements pass the predicate function func Find[T any](slice []T, predicate func(index int, t T) bool) (*T, bool) //iterates over elements of slice, returning the first one that passes a truth test on iteratee function. If return T is nil then no items matched the predicate func +func FindLast[T any](slice []T, predicate func(index int, t T) bool) (*T, bool) //iterates over elements of slice from end to begin, returning the first one that passes a truth test on predicate function. if return T is nil then no items matched the predicate func func FlattenDeep(slice interface{}) interface{} //flattens slice recursive func ForEach [T any] (slice []T, iteratee func(index int, t T)) //iterates over elements of slice and invokes function for each element func IntSlice(slice interface{}) ([]int, error) //convert value to int slice diff --git a/README_zh-CN.md b/README_zh-CN.md index ddb54fb..af8ad60 100644 --- a/README_zh-CN.md +++ b/README_zh-CN.md @@ -438,12 +438,14 @@ func Chunk[T any](slice []T, size int) [][]T //均分slice func Compact[T any](slice []T) []T //去除slice中的false vule. false values are false, nil, 0, and "" func Concat[T any](slice []T, values ...[]T) []T //连接values到slice中 func Difference[T comparable](slice1, slice2 []T) []T //返回切片,其元素在slice1中,不在slice2中 -func DifferenceBy[T any](slice []T, comparedSlice []T, iteratee func(index int, t T) T) []T //将slice 和comparedSlice中每个元素调用iterateeFn后作比较,如果不相等返回slice中的元素。 +func DifferenceBy[T any](slice []T, comparedSlice []T, iteratee func(index int, t T) T) []T //将slice 和comparedSlice中每个元素调用iterateeFn后作比较,如果不相等返回slice中的元素 +func DifferenceWith[T any](slice []T, comparedSlice []T, comparator func(value, otherValue T) bool) []T //将slice 和comparedSlice中每个元素调用comparator后作比较,如果为false,返回slice中的元素 func DeleteByIndex[T any](slice []T, start int, end ...int) []T //删除切片中start到end位置的值(不包含end) func Drop[T any](slice []T, n int) []T //创建一个新切片,当n大于0时删除原切片前n个元素,当n小于0时删除原切片后n个元素 func Every[T any](slice []T, predicate func(index int, t T) bool) bool//slice中所有元素都符合函数条件时返回true, 否则返回false func None[T any](slice []T, predicate func(index int, t T) bool) bool //slice中所有元素都不符合函数条件时返回true, 否则返回false -func Find[T any](slice []T, predicate func(index int, t T) bool) (*T, bool) //查找slice中第一个符合条件的元素,没有找到时返回nil +func Find[T any](slice []T, predicate func(index int, t T) bool) (*T, bool) //查找slice中第一个符合条件的元素,没有找到时返回nil, false +func FindLast[T any](slice []T, predicate func(index int, t T) bool) (*T, bool) //从后往前查找slice中第一个符合条件的元素,没有找到时返回nil, false func Filter [T any] (slice []T, predicate func(index int, t T) bool) []T//过滤slice中元素符合predicate函数 func FlattenDeep(slice interface{}) interface{} //将slice递归为一维切片 func ForEach [T any] (slice []T, iteratee func(index int, t T)) //遍历切片,在每个元素上执行iteratee函数 diff --git a/slice/slice.go b/slice/slice.go index 9fdd219..d450514 100644 --- a/slice/slice.go +++ b/slice/slice.go @@ -257,10 +257,10 @@ func GroupBy[T any](slice []T, groupFn func(index int, t T) bool) ([]T, []T) { return groupA, groupB } -// Find iterates over elements of slice, returning the first one that passes a truth test on iteratee function. +// Find iterates over elements of slice, returning the first one that passes a truth test on predicate function. // If return T is nil then no items matched the predicate func -func Find[T any](slice []T, iteratee func(index int, t T) bool) (*T, bool) { - if iteratee == nil { +func Find[T any](slice []T, predicate func(index int, t T) bool) (*T, bool) { + if predicate == nil { panic("fn is missing") } @@ -270,7 +270,33 @@ func Find[T any](slice []T, iteratee func(index int, t T) bool) (*T, bool) { index := -1 for i, v := range slice { - if iteratee(i, v) { + if predicate(i, v) { + index = i + break + } + } + + if index == -1 { + return nil, false + } + + return &slice[index], true +} + +// FindLast iterates over elements of slice from end to begin, returning the first one that passes a truth test on predicate function. +// If return T is nil then no items matched the predicate func +func FindLast[T any](slice []T, predicate func(index int, t T) bool) (*T, bool) { + if predicate == nil { + panic("fn is missing") + } + + if len(slice) == 0 { + return nil, false + } + + index := -1 + for i := len(slice) - 1; i >= 0; i-- { + if predicate(i, slice[i]) { index = i break } diff --git a/slice/slice_test.go b/slice/slice_test.go index 56d7ffe..4e5bca5 100644 --- a/slice/slice_test.go +++ b/slice/slice_test.go @@ -166,6 +166,20 @@ func TestFind(t *testing.T) { assert.Equal(2, *res) } +func TestFindLast(t *testing.T) { + nums := []int{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, "TestFindLast") + assert.Equal(4, *res) +} + func TestFindFoundNothing(t *testing.T) { nums := []int{1, 1, 1, 1, 1, 1} findFunc := func(i, num int) bool {