Skip to content

Commit

Permalink
Update document + correct group function
Browse files Browse the repository at this point in the history
  • Loading branch information
ledongthuc committed Jan 2, 2022
1 parent 63ca023 commit 0d42f88
Show file tree
Hide file tree
Showing 15 changed files with 45 additions and 20 deletions.
32 changes: 16 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

![goterators-Thumbnail](https://user-images.githubusercontent.com/1828895/147876484-5bc7cfd0-5f14-4889-a3f0-64cb307b7765.png)

- Goterators is util library that Supports aggregate & transforms functions Go, including:
- Goterators is util library that support aggregate & transforms functions list in Go, including:
- [for-each](#for-each)
- [find](#find)
- [exist](#exist)
Expand All @@ -15,7 +15,7 @@
- [some](#some)
- [flat](#flat)

- API and functions are inspired from Rust and Javascript.
- The API and functions are inspired by Rust and Javascript.

# Requirement

Expand Down Expand Up @@ -45,7 +45,7 @@ import "github.com/ledongthuc/goterators"

![goterators-ForEach](https://user-images.githubusercontent.com/1828895/147876359-432c3122-25f3-492e-844d-6172eafe92a6.png)

- For-each function act the same `for` in Go. Just another option to loop through items in a list.
- For-each function does the same `for` in Go. Just another option to loop through items in a list.

```go
ForEach(list1, func(item int) {
Expand All @@ -65,7 +65,7 @@ ForEach(list3, func(item MyStruct) {

![goterators-Find](https://user-images.githubusercontent.com/1828895/147876363-245705c5-2aa8-4135-8d29-5cbaca173529.png)

- Find function return first element and its index in the list that meets function condition. In case no element meet the condition function, return the error "Not Found".
- Find function returns the first element and its index in the list that meets the functional condition. If no element meet the condition function, return the error "Not Found".

```go
matchedInt, index, err := Find(list, func(item int) bool {
Expand All @@ -85,7 +85,7 @@ matchedStruct, index, err := Find(list, func(item MyStruct) bool {

![goterators-Exist](https://user-images.githubusercontent.com/1828895/147876367-c0c7fd50-1888-4152-a7c8-5960ca26b6d9.png)

- Exist check an existence of element in the list
- Exist function checks the existence of an element in the list.

```go
matchedInt, err := Exist(list, 1)
Expand All @@ -99,11 +99,11 @@ matchedStruct, err := Exist(list, SearchingStruct)

![goterators-Reduce](https://user-images.githubusercontent.com/1828895/147876373-4cb1f784-b9d4-4b95-a4f9-30709ba3690d.png)

- Similar to Fold Left, Reduce function run the reducer function on each element of array. In order, the reduce function passes in the return value from calculation on the preceding element. The final result of running the reducer across all elements of the array is the return value of final reducer on last element.
- Similar to Fold Left, Reduce function runs the reducer function on each element of the array. In order, the reduce function passes in the return value from the calculation on the preceding element. The final result of running the reducer across all elements of the array is the return value of the final reducer on the last element.
- Reduce function has 3 parameters:
- list: source list we want to process.
- initial value: the previous value that's used in reducer call of first element. At this time, previous = initial value, current = first element of list.
- reducer function: the function will run on all elements of source list.
- initial value: the previous value that's used in the reducer call of the first element. At this time, previous = initial value, current = first element of the list.
- reducer function: the function will run on all elements of the source list.

```go
// Sum
Expand All @@ -121,11 +121,11 @@ items := Reduce(testSource, []float64{}, func(previous []float64, current int, i

![goterators-Reduce right](https://user-images.githubusercontent.com/1828895/147876376-1f168d48-3ba5-4d44-aa0a-4e1c36505be5.png)

- Similar to Fold Right, Reduce function run the reducer function on each element of array, from last to first element. In order, the reduce function passes in the return value from calculation on the preceding element. The final result of running the reducer across all elements of the array is the return value of final reducer on first element.
- Similar to Fold Right, Reduce right function run the reducer function on each element of the array, from last to the first element. In order, the reduce function passes in the return value from the calculation on the preceding element. The final result of running the reducer across all elements of the array is the return value of the final reducer on the first element.
- Reduce function has 3 parameters:
- list: source list we want to process.
- initial value: the previous value that's used in reducer call of last element. At this time, previous = initial value, current = last element of list.
- reducer function: the function will run on all elements of source list.
- initial value: the previous value that's used in the reducer call of the last element. At this time, previous = initial value, current = last element of list.
- reducer function: the function will run on all elements of the source list.

```go
// Reverse
Expand All @@ -138,7 +138,7 @@ reversedList := Reduce(list, []string{}, func(previous []string, current string,

![goterators-Filter](https://user-images.githubusercontent.com/1828895/147876377-6df6ea14-6fb7-478c-9671-e6ca7c6e2a97.png)

- Filter function filters items that meets function condition
- Filter function return items that pass the filter function.

```go
filteredItems, err := Filter(list, func(item int) bool {
Expand All @@ -158,7 +158,7 @@ filteredItems, err := Filter(list, func(item MyStruct) bool {

![goterators-Map](https://user-images.githubusercontent.com/1828895/147876383-5d701c6e-fb65-442f-b5ed-e97d30c23115.png)

- Map function convert items in the list to output list
- Map function converts items in the list to the output list.

```go
mappedItems := Map(testSource, func(item int64) float64 {
Expand All @@ -174,7 +174,7 @@ prices := Map(testSource, func(item Order) Price {

![goterators-Every](https://user-images.githubusercontent.com/1828895/147876387-520ee3b5-2846-4052-ad35-dd57d8741bd1.png)

- Every function check all elements in the list meet the condition, return true. Otherwise, return false.
- Every function checks all elements in the list with condition function. If it's yes return true; otherwise, return false.

```go
valid := Every(list, func(item int) bool { item % 2 == 0 })
Expand All @@ -198,7 +198,7 @@ valid := Some(list, func(item string) bool { len(item) < 20 })

![goterators-Group](https://user-images.githubusercontent.com/1828895/147878206-bef39880-96db-4269-b54e-2dcbb06f6bac.png)

- Group function group elements into nested list by group condition.
- Group groups elements into the nested level. Use a build-group function to define group type.

```
groups := Group(list, func(item Product) groupKey {
Expand All @@ -210,7 +210,7 @@ groups := Group(list, func(item Product) groupKey {

![goterators-Flat](https://user-images.githubusercontent.com/1828895/147876403-25e84044-d761-45b7-b126-6ad8a7c5a4d1.png)

- Flat function return new array with all sub-array elements concatenated with 1 level depth.
- Flat returns a new array with all sub-array elements concatenated with 1 level depth.

```go
output := Flat([][]int{{1,2}, {3}}) // output = {1,2,3}
Expand Down
2 changes: 2 additions & 0 deletions doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Package goterators provides utility functions that support aggregate & transforms list in Go.
package goterators
1 change: 1 addition & 0 deletions errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ package goterators
import "fmt"

var (
// ErrNotFound is used in functions that need to find any items in the list but are not found.
ErrNotFound = fmt.Errorf("not found")
)
1 change: 1 addition & 0 deletions every.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package goterators

// Every checks all elements in the list with condition function. If it's yes return true; otherwise, return false.
func Every[T comparable](source []T, conditionFunc func(item T) bool) bool {
for _, item := range source {
if !conditionFunc(item) {
Expand Down
1 change: 1 addition & 0 deletions exist.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package goterators

// Exist checks the existence of an element in the list.
func Exist[T comparable](source []T, checkingItem T) bool {
_, _, err := Find[T](source, func(item T) bool {
return item == checkingItem
Expand Down
1 change: 1 addition & 0 deletions filter.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package goterators

// Filter return items that pass the filter function.
func Filter[T any](source []T, filteredFunc func(item T) bool) (output []T) {
for _, item := range source {
if filteredFunc(item) {
Expand Down
1 change: 1 addition & 0 deletions find.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package goterators

// Find returns the first element and its index in the list that meets the functional condition. If no element meet the condition function, return the error "Not Found".
func Find[T any](source []T, matchedItemFunc func(item T) bool) (t T, index int, err error) {
for index, item := range source {
if matchedItemFunc(item) {
Expand Down
1 change: 1 addition & 0 deletions flat.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package goterators

// Flat returns a new array with all sub-array elements concatenated with 1 level depth.
func Flat[T any](source [][]T) []T {
outputSize := 0
for _, group := range source {
Expand Down
1 change: 1 addition & 0 deletions foreach.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package goterators

// ForEach does the same `for` in Go. Just another option to loop through items in a list.
func ForEach[T any](source []T, handler func(item T)) {
for _, item := range source {
handler(item)
Expand Down
10 changes: 8 additions & 2 deletions group.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
package goterators

// Group groups elements into the nested level. Use a build-group function to define group type.
func Group[T any, G comparable](source []T, buildGroup func(item T) G) [][]T {
output := map[G][]T{}
m := map[G][]T{}
for index, item := range source {
group := buildGroup(item)
output[group] = append(output[group], source[index])
m[group] = append(m[group], source[index])
}

output := make([][]T, 0, len(m))
for key := range m {
output = append(output, m[key])
}
return output
}
4 changes: 2 additions & 2 deletions group_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ func TestGroup(t *testing.T) {
}
for groupIndex := range expectedItems {
if len(expectedItems[groupIndex]) != len(actualItems[groupIndex]) {
t.Fatalf("Group index %v, expected = %v, actual = %v", groupIndex, expectedItems[key], actualItems[key])
t.Fatalf("Group index %v, expected = %v, actual = %v", groupIndex, expectedItems[groupIndex], actualItems[groupIndex])
}
for index := range expectedItems[groupIndex] {
if expectedItems[groupIndex][index] != actualItems[groupIndex][index] {
t.Errorf("Group index %v, Index %v, expected = %v, actual = %v", groupIndex, index, expectedItems[key][index], actualItems[key][index])
t.Errorf("Group index %v, Index %v, expected = %v, actual = %v", groupIndex, index, expectedItems[groupIndex][index], actualItems[groupIndex][index])
}
}
}
Expand Down
1 change: 1 addition & 0 deletions map.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package goterators

// Map function converts items in the list to the output list.
func Map[T1 any, T2 any](source []T1, mappingFunc func(item T1) T2) (output []T2) {
for _, item := range source {
output = append(output, mappingFunc(item))
Expand Down
4 changes: 4 additions & 0 deletions reduce.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package goterators

/*Reduce runs the reducer function on each element of the array. In order, the reduce function passes in the return value from the calculation on the preceding element. The final result of running the reducer across all elements of the array is the return value of the final reducer on the last element.
- list paramerter: source list we want to process.
- initial value paramerter: the previous value that's used in the reducer call of the first element. At this time, previous = initial value, current = first element of the list.
- reducer function paramerter: the function will run on all elements of the source list.*/
func Reduce[T1 any, T2 any](source []T1, initialValue T2, reducer func(previousValue T2, currentValue T1, currentIndex int, list []T1) T2) T2 {
previousItem := initialValue
output := initialValue
Expand Down
4 changes: 4 additions & 0 deletions reduce_right.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package goterators

/* ReduceRight runs the reducer function on each element of the array, from last to the first element. In order, the reduce function passes in the return value from the calculation on the preceding element. The final result of running the reducer across all elements of the array is the return value of the final reducer on the first element.
- list parameter: source list we want to process.
- initial value parameter: the previous value that's used in the reducer call of the last element. At this time, previous = initial value, current = last element of list.
- reducer function parameter: the function will run on all elements of the source list.*/
func ReduceRight[T1 any, T2 any](source []T1, initialValue T2, reducer func(previousValue T2, currentValue T1, currentIndex int, list []T1) T2) T2 {
previousItem := initialValue
output := initialValue
Expand Down
1 change: 1 addition & 0 deletions some.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package goterators

// Some checks at least one element in the list meet the condition; return true, or return false if all elements don't meet the condition.
func Some[T comparable](source []T, conditionFunc func(item T) bool) bool {
for _, item := range source {
if conditionFunc(item) {
Expand Down

0 comments on commit 0d42f88

Please sign in to comment.