patterngoModerate
in_array() in Go
Viewed 0 times
in_arraystackoverflowprogramming
Problem
This function's objective is very simple. It takes
Could this be coded in a better way? How would I implement this to work with any kind of array (the code below works only with arrays of strings)?
Go probably provides a similar function, but this is for study purposes only.
array and checks if val is a value inside of this array. It returns whether val exists and which is the index inside the array that contains val.Could this be coded in a better way? How would I implement this to work with any kind of array (the code below works only with arrays of strings)?
package main
import "fmt"
func in_array(val string, array []string) (exists bool, index int) {
exists = false
index = -1;
for i, v := range array {
if val == v {
index = i
exists = true
return
}
}
return
}
func main() {
names := []string{ "Mary", "Anna", "Beth", "Johnny", "Beth" }
fmt.Println( in_array("Jack", names) )
}Go probably provides a similar function, but this is for study purposes only.
Solution
Rather than tie yourself to only one type (string), you could use the
Note that we now import the
In our inner code, we get the value of the
Running the main function with both a slice of strings and a slice of integers, as follows, works:
The above example gets us:
EDIT: June 2021 - refactored the above code as follows:
with the runner function:
reflect package as well as interfaces to make it somewhat type indifferent. The following is my reworking of your code:package main
import "fmt"
import "reflect"
func in_array(val interface{}, array interface{}) (exists bool, index int) {
exists = false
index = -1
switch reflect.TypeOf(array).Kind() {
case reflect.Slice:
s := reflect.ValueOf(array)
for i := 0; i < s.Len(); i++ {
if reflect.DeepEqual(val, s.Index(i).Interface()) == true {
index = i
exists = true
return
}
}
}
return
}Note that we now import the
reflect package. We also changed the types of val and array to interface{} so that we may pass any type in. We then use the reflect.Typeof() to glean the reflection reflect.Type of the value in the array interface{}. We then glean the type with Kind(), and use a case to fall into our inner code if its a slice (can add more cases to extend this).In our inner code, we get the value of the
array argument, and store it in s. We then iterate over the length of s, and compare val to s at the index i declared as an interface with Interface() and check for truthiness. If its true, we exit with a true and the index.Running the main function with both a slice of strings and a slice of integers, as follows, works:
func main() {
names := []string{"Mary", "Anna", "Beth", "Johnny", "Beth"}
fmt.Println(in_array("Anna", names))
fmt.Println(in_array("Jon", names))
ints := []int{1, 4, 3, 2, 6}
fmt.Println(in_array(3, ints))
fmt.Println(in_array(95, ints))
}The above example gets us:
true 1
false -1
true 2
false -1EDIT: June 2021 - refactored the above code as follows:
func inArray(val interface{}, array interface{}) (index int) {
values := reflect.ValueOf(array)
if reflect.TypeOf(array).Kind() == reflect.Slice || values.Len() > 0 {
for i := 0; i < values.Len(); i++ {
if reflect.DeepEqual(val, values.Index(i).Interface()) {
return i
}
}
}
return -1
}with the runner function:
func main() {
name := "Mary Anna"
fmt.Println(inArray("Anna", name))
var empty []string
fmt.Println(inArray("Anna", empty))
names := []string{"Mary", "Anna", "Beth", "Johnny", "Beth"}
fmt.Println(inArray("Anna", names))
fmt.Println(inArray("Jon", names))
ints := []int{1, 4, 3, 2, 6}
fmt.Println(inArray(3, ints))
fmt.Println(inArray(95, ints))
}Code Snippets
package main
import "fmt"
import "reflect"
func in_array(val interface{}, array interface{}) (exists bool, index int) {
exists = false
index = -1
switch reflect.TypeOf(array).Kind() {
case reflect.Slice:
s := reflect.ValueOf(array)
for i := 0; i < s.Len(); i++ {
if reflect.DeepEqual(val, s.Index(i).Interface()) == true {
index = i
exists = true
return
}
}
}
return
}func main() {
names := []string{"Mary", "Anna", "Beth", "Johnny", "Beth"}
fmt.Println(in_array("Anna", names))
fmt.Println(in_array("Jon", names))
ints := []int{1, 4, 3, 2, 6}
fmt.Println(in_array(3, ints))
fmt.Println(in_array(95, ints))
}true 1
false -1
true 2
false -1func inArray(val interface{}, array interface{}) (index int) {
values := reflect.ValueOf(array)
if reflect.TypeOf(array).Kind() == reflect.Slice || values.Len() > 0 {
for i := 0; i < values.Len(); i++ {
if reflect.DeepEqual(val, values.Index(i).Interface()) {
return i
}
}
}
return -1
}func main() {
name := "Mary Anna"
fmt.Println(inArray("Anna", name))
var empty []string
fmt.Println(inArray("Anna", empty))
names := []string{"Mary", "Anna", "Beth", "Johnny", "Beth"}
fmt.Println(inArray("Anna", names))
fmt.Println(inArray("Jon", names))
ints := []int{1, 4, 3, 2, 6}
fmt.Println(inArray(3, ints))
fmt.Println(inArray(95, ints))
}Context
StackExchange Code Review Q#60074, answer score: 19
Revisions (0)
No revisions yet.