Total Lines | 36 |
Duplicated Lines | 0 % |
Changes | 0 |
1 | package internal |
||
2 | |||
3 | import ( |
||
4 | "reflect" |
||
5 | |||
6 | "github.com/gotilty/gotil/internal/errs" |
||
7 | ) |
||
8 | |||
9 | // Reduce iterates given collection and returns the accumulated result of running each element |
||
10 | // the last param is initial value of accumulator. |
||
11 | // data := []int{5, 10} |
||
12 | // result, _ := Reduce(data, func(accumulator, val interface{}, i int) interface{} { |
||
13 | // return accumulator.(int) + val.(int) |
||
14 | // }, 0) |
||
15 | // // Output: 15 |
||
16 | func Reduce(a interface{}, f func(accumulator interface{}, val interface{}, i int) interface{}, accumulator interface{}) (interface{}, error) { |
||
17 | val := reflect.ValueOf(a) |
||
18 | switch val.Kind() { |
||
19 | case reflect.Slice, reflect.Array: |
||
20 | length := val.Len() |
||
21 | index := -1 |
||
22 | newSlice := copySlice(a) |
||
23 | if IsAssigned(accumulator) && length > 0 { |
||
24 | index++ |
||
25 | accumulator = newSlice.Index(index).Interface() |
||
26 | } |
||
27 | index++ |
||
28 | for index < length { |
||
29 | |||
30 | rowVal := val.Index(index) |
||
31 | accumulator = f(accumulator, rowVal.Interface(), index) |
||
32 | index++ |
||
33 | } |
||
34 | return accumulator, nil |
||
35 | } |
||
36 | return nil, errs.NewUnsupportedTypeError(val.Kind().String()) |
||
37 | } |
||
38 |