0

Suppose there is an slice having integers in it. And we have declared a variable which contains a integer value then I have to find the value from that slice without using for loop.

Using for loop I do like this:-

package main

import (
   "fmt"
)

func main() {
  value := 10
  var interf []interface{}
  for i := 1; i <= value; i++{
    interf = append(interf, i)
  } 
  fmt.Println(interf)
  for _,v := range interf{
    if value == v{
       fmt.Println("Matched")
    }
  }
}

How we do this same thing without using for loop

icza
  • 389,944
  • 63
  • 907
  • 827
Doe
  • 91
  • 1
  • 3
  • 10
  • 4
    There, golang has no method for this. You can read more [here](https://stackoverflow.com/a/38654444/3351097) – Maxian Nicu Oct 24 '18 at 09:26
  • @MaxianNicu https://play.golang.org/p/PGx3gRSgjMx this is a playground and please tell me how I implement it in my code – Doe Oct 24 '18 at 09:32
  • 1
    One way or another, the for loop is unavoidable. You need to at least look at the values in the slice once to tell if it's there or not, which takes a loop or something similar in complexity (O(n) that is). If you think it's repetitive or boring to look at, you can just abstract it away in a function. – catsafety Oct 24 '18 at 11:05

1 Answers1

2

Without a for loop, no* (see How to search for an element in a golang slice).

* Actually you could do it without a for loop using a recursive function. See solution at the end of the answer.

There is no ready function for this in the standard library, but this is how easy it is to create one yourself:

func find(what interface{}, where []interface{}) (idx int) {
    for i, v := range where {
        if v == what {
            return i
        }
    }
    return -1
}

And using it:

what := 10
where := []interface{}{1, 2, 3, 10, 5}
fmt.Println(find(what, where))

Output (try it on the Go Playground):

3

Also note that it would be faster and more convenient to use []int slice type instead of []interface{}:

func find(what int, where []int) (idx int) {
    for i, v := range where {
        if v == what {
            return i
        }
    }
    return -1
}

And then using it:

what := 10
where := []int{1, 2, 3, 10, 5}
fmt.Println(find(what, where))

Output is the same. Try this one on the Go Playground.

You could create a function that accepts slices of any type using the interface{} type, but that would require reflection to implement it, which would be slower and not worthy to be used. Instead just create a function with concrete slice types if you need, or just use the for loop in place.

For completeness, here's the solution that uses no for loops but a recursive function. This is here only for educational purposes, the solutions above are superior to this:

func find(what int, where []int) (idx int) {
    if len(where) == 0 {
        return -1
    }
    if what == where[0] {
        return 0
    }
    if idx = find(what, where[1:]); idx < 0 {
        return -1 // Not found in the rest of the slice
    }
    return 1 + idx
}

Try this one on the Go Playground.

markonius
  • 625
  • 6
  • 25
icza
  • 389,944
  • 63
  • 907
  • 827