diff --git a/slice/slice.go b/slice/slice.go index e091a85..23cd771 100644 --- a/slice/slice.go +++ b/slice/slice.go @@ -89,6 +89,50 @@ func Difference(slice1, slice2 interface{}) interface{} { return res.Interface() } +// Every return true if all of the values in the slice pass the predicate function. +// The function signature should be func(index int, value interface{}) bool . +func Every(slice, function interface{}) bool { + 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 indexes []int + for i := 0; i < sv.Len(); i++ { + flag := fn.Call([]reflect.Value{reflect.ValueOf(i), sv.Index(i)})[0] + if flag.Bool() { + indexes = append(indexes, i) + } + } + + return len(indexes) == sv.Len() +} + +// Some return true if any of the values in the list pass the predicate function. +// The function signature should be func(index int, value interface{}) bool . +func Some(slice, function interface{}) bool { + 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 indexes []int + for i := 0; i < sv.Len(); i++ { + flag := fn.Call([]reflect.Value{reflect.ValueOf(i), sv.Index(i)})[0] + if flag.Bool() { + indexes = append(indexes, i) + } + } + + return len(indexes) > 0 +} + // Filter iterates over elements of slice, returning an slice of all elements `signature` returns truthy for. // The function signature should be func(index int, value interface{}) bool . func Filter(slice, function interface{}) interface{} { diff --git a/slice/slice_test.go b/slice/slice_test.go index 2f020af..20699db 100644 --- a/slice/slice_test.go +++ b/slice/slice_test.go @@ -96,15 +96,39 @@ func TestConvertSlice(t *testing.T) { //} } +func TestEvery(t *testing.T) { + nums := []int{1, 2, 3, 5} + isEven := func(i, num int) bool { + return num%2 == 0 + } + res := Every(nums, isEven) + if res != false { + utils.LogFailedTestInfo(t, "Every", nums, false, res) + t.FailNow() + } +} + +func TestSome(t *testing.T) { + nums := []int{1, 2, 3, 5} + isEven := func(i, num int) bool { + return num%2 == 0 + } + res := Some(nums, isEven) + if res != true { + utils.LogFailedTestInfo(t, "Some", nums, true, res) + t.FailNow() + } +} + func TestFilter(t *testing.T) { - s1 := []int{1, 2, 3, 4, 5} + nums := []int{1, 2, 3, 4, 5} even := func(i, num int) bool { return num%2 == 0 } e1 := []int{2, 4} - r1 := Filter(s1, even) + r1 := Filter(nums, even) if !reflect.DeepEqual(r1, e1) { - utils.LogFailedTestInfo(t, "Filter", s1, e1, r1) + utils.LogFailedTestInfo(t, "Filter", nums, e1, r1) t.FailNow() }