Skip to content

Commit 2bc1afd

Browse files
committed
Added find index and it's test
1 parent 1aa87b1 commit 2bc1afd

File tree

5 files changed

+119
-55
lines changed

5 files changed

+119
-55
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,16 @@ users := []User{{Id: 10, Name: "Go"}, {Id: 11, Name: "Lang"}}
2626
2727
```
2828

29+
### Find
30+
31+
```
32+
user, err := js.Find(users, func(user User, index int) bool {
33+
return user.Id == 10
34+
})
35+
// {Id: 10, Name: "Go"}
36+
37+
```
38+
2939
### Filter
3040

3141
```

find_index_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package js_array_method
2+
3+
import "testing"
4+
5+
func TestFindIndexWithCallback(t *testing.T) {
6+
users := []User{{Id: 10, Name: "John"}, {Id: 11, Name: "Doe"}, {Id: 12, Name: "Sabrina"}}
7+
8+
index := FindIndex(users, func(user User, _ int) bool {
9+
return user.Name == "Doe"
10+
})
11+
12+
if index == -1 || index == 2 {
13+
t.Errorf("Expected 1 got %d", index)
14+
}
15+
16+
index = FindIndex(users, func(user User, _ int) bool {
17+
return user.Name == "creator"
18+
})
19+
20+
if index != -1 {
21+
t.Errorf("Expected -1 got %d", index)
22+
}
23+
}
24+
25+
func TestFindIndexWithoutCallback(t *testing.T) {
26+
users := []string{"User1", "User2", "User3", "User4"}
27+
28+
index := FindIndex(users, "User1")
29+
30+
if index != 0 {
31+
t.Errorf("Expected 0 got %d", index)
32+
}
33+
34+
index = FindIndex(users, "User5")
35+
36+
if index != -1 {
37+
t.Errorf("Expected -1 got %d", index)
38+
}
39+
}

find_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,21 @@ import "testing"
55
func TestFindWithStructSlice(t *testing.T) {
66
users := []User{{Id: 10, Name: "Go"}, {Id: 11, Name: "Lang"}}
77

8-
user := Find(users, func(user User, index int) bool {
8+
user, err := Find(users, func(user User, index int) bool {
99
return user.Id == 10
1010
})
1111

1212
expected := "Go"
1313

14-
if user.Name != expected {
14+
if err != nil {
1515
t.Errorf("Expected %s received %s", expected, user.Name)
1616
}
1717
}
1818

1919
func TestFindWithStringSlice(t *testing.T) {
2020
var slices = []string{"Go", "Typescript", "Nodejs"}
2121

22-
ln := Find(slices, "Go")
22+
ln, _ := Find(slices, "Go")
2323

2424
expected := "Go"
2525

js_array_method.go

Lines changed: 27 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
package js_array_method
22

33
import (
4-
"fmt"
5-
"reflect"
4+
"errors"
65
)
76

7+
func Foreach[T any](input []T, callback func(element T, index int)) {
8+
for index, value := range input {
9+
callback(value, index)
10+
}
11+
}
12+
813
func Map[T any, U any](input []T, callback func(element T, index int) U) []U {
914
var output []U
1015

@@ -50,60 +55,36 @@ func Reduce[T any, U any](input []T, callback func(pre U, current T, index int)
5055
// conditions can be callback or a value
5156
// callback has two parameter one is element and another is index
5257
// callback must return true or false
53-
func Find[T any](input []T, conditions interface{}) T {
58+
func Find[T any](input []T, conditions interface{}) (T, error) {
5459
var item T
55-
conditionType := getType(conditions)
56-
for index, value := range input {
57-
if conditionType == "func" && callCallback(conditions, value, index) {
58-
item = value
59-
break
60-
} else if conditionType != "func" && compareValue(conditions, value) {
61-
item = value
62-
break
63-
}
64-
}
60+
index := FindIndex(input, conditions)
6561

66-
return item
67-
}
68-
69-
func Foreach[T any](input []T, callback func(element T, index int)) {
70-
for index, value := range input {
71-
callback(value, index)
62+
if index < 0 {
63+
return item, errors.New("nothing found")
7264
}
73-
}
7465

75-
func callCallback[T any](conditions interface{}, value T, index int) bool {
76-
res := reflect.ValueOf(conditions).Call([]reflect.Value{reflect.ValueOf(value), reflect.ValueOf(index)})
66+
item = input[index]
7767

78-
return res[0].Bool()
68+
return item, nil
7969
}
8070

81-
func compareValue[T any](conditions interface{}, value T) bool {
82-
res := reflect.ValueOf(conditions).String()
83-
return res == fmt.Sprintf("%v", value)
84-
}
85-
86-
func getType(conditions interface{}) string {
87-
return reflect.TypeOf(conditions).Kind().String()
88-
}
89-
90-
func calculateEveryElement[T any](input []T, conditions interface{}) []bool {
91-
output := []bool{}
92-
71+
// conditions can be callback or a value
72+
// callback has two parameter one is element and another is index
73+
// callback must return true or false
74+
func FindIndex[T any](input []T, conditions interface{}) int {
75+
var itemIndex int = -1
9376
conditionType := getType(conditions)
9477
for index, value := range input {
95-
result := false
96-
if conditionType == "func" {
97-
result = callCallback(conditions, value, index)
98-
} else {
99-
result = compareValue(conditions, value)
100-
}
101-
if result {
102-
output = append(output, true)
78+
if conditionType == "func" && callCallback(conditions, value, index) {
79+
itemIndex = index
80+
break
81+
} else if conditionType != "func" && compareValue(conditions, value) {
82+
itemIndex = index
83+
break
10384
}
10485
}
10586

106-
return output
87+
return itemIndex
10788
}
10889

10990
// conditions can be callback or a value
@@ -126,14 +107,8 @@ func Some[T any](input []T, conditions interface{}) any {
126107
// callback has two parameter one is element and another is index
127108
// callback must return true or false
128109
func Includes[T any](input []T, conditions interface{}) bool {
129-
result := Find(input, conditions)
130-
131-
if getType(result) == "struct" && reflect.ValueOf(result).IsZero() {
132-
return false
133-
} else if getType(result) != "struct" && fmt.Sprintf("%v", result) == "" {
134-
return false
135-
}
136-
return true
110+
result := FindIndex(input, conditions)
111+
return result >= 0
137112
}
138113

139114
func Reverse[T any](input []T) []T {

util.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package js_array_method
2+
3+
import (
4+
"fmt"
5+
"reflect"
6+
)
7+
8+
func callCallback[T any](conditions interface{}, value T, index int) bool {
9+
res := reflect.ValueOf(conditions).Call([]reflect.Value{reflect.ValueOf(value), reflect.ValueOf(index)})
10+
11+
return res[0].Bool()
12+
}
13+
14+
func compareValue[T any](conditions interface{}, value T) bool {
15+
res := reflect.ValueOf(conditions).String()
16+
return res == fmt.Sprintf("%v", value)
17+
}
18+
19+
func getType(conditions interface{}) string {
20+
return reflect.TypeOf(conditions).Kind().String()
21+
}
22+
23+
func calculateEveryElement[T any](input []T, conditions interface{}) []bool {
24+
output := []bool{}
25+
26+
conditionType := getType(conditions)
27+
for index, value := range input {
28+
result := false
29+
if conditionType == "func" {
30+
result = callCallback(conditions, value, index)
31+
} else {
32+
result = compareValue(conditions, value)
33+
}
34+
if result {
35+
output = append(output, true)
36+
}
37+
}
38+
39+
return output
40+
}

0 commit comments

Comments
 (0)