I'm trying to build simple function to count elements in slice (like len) It must be simple (without additional libs) and with recursion. The problem is when i try to check is slice is empty (is nul).
package main
import "fmt"
func main() {
x := []int{1, 2, 3}
fmt.Println(len2(x))
}
func len2(s []int) int {
if s == nil {
return 0
}
return 1 + len2(s[1:])
}
the result it should be in this example '3'.
It's broken in if s == nil:
panic: runtime error: slice bounds out of range
It panics because you have no valid termination condition.
When your len2() is called with a non-nil empty slice, it attempts to slice it like s[1:], which will be a runtime panic.
Instead of checking for nil slice, check if the slice is empty by comparing its length to 0:
func len2(s []int) int {
if len(s) == 0 {
return 0
}
return 1 + len2(s[1:])
}
Try it on the Go Playground.
If you can't use the builtin len() function (which you already did in your solution), you may use the for ... range:
func len2(s []int) int {
size := 0
for i := range s {
size = i + 1
}
return size
}
Try this on the Go Playground.
And if it must be recursive, then for example:
func len2(s []int) int {
size := 0
for range s {
size = 1 + len2(s[1:])
break
}
return size
}
Try this on the Go Playground.
But know that these are awful solutions compared to using the builtin len().
The following is not a solution with better performance than len but an implementation that does not use any extra libraries and depends on recursion to find length
func len2(s []int) (count int) {
defer func() {
if r := recover(); r != nil {
count = 0
}
}()
return 1 + len2(s[1:])
}
Here is sample code
package main
import "fmt"
func main() {
var x []int = nil
var x1 = []int{1, 2, 3, 4}
var x2 = []int{}
var x3 = make([]int, 10, 20)
fmt.Println(len2(x))
fmt.Println(len2(x1))
fmt.Println(len2(x2))
fmt.Println(len2(x3))
}
func len2(s []int) (count int) {
defer func() {
if r := recover(); r != nil {
count = 0
}
}()
return 1 + len2(s[1:])
}
Checkout the same in playground
If you can leave without recursion here is a function that does not use len() and should be faster then re-slicing recursively.
func len2(s []int) (count int) {
for i := range s {
count = i + 1
}
}
If you do not want to use len() func, you can use cap()
func main() {
x := []int{1, 2, 3}
fmt.Println(len2(x))
}
func len2(s []int) int {
if cap(s) == 0 {
return 0
}
return 1 + len2(s[1:])
}
Try it again
Original Answer:
In order to check if an array (slice) is empty, you should use the function len()
if len(s) == 0 {
return 0
}
Try it
Related
Combinations can be printed using the following recursive code (inspired from Rosetta)
I thought it would be easy to store the intermediate results in an []int or the set of combination in an [][]int. But, because the function is recursive, it is not so easy than replacing the
fmt.Println(s)
by a
return s
with a minor modification of the function output for example. I also tried to feed a pointer like
p *[][]int
with the variable "s" inside the recursive function, but I failed :-/
I think it is a general problem with recursive functions so if you have some advises to solve this problem it will help me a lot !
Many thanks in advance ! ;)
package main
import (
"fmt"
)
func main() {
comb(5, 3)
}
func comb(n, m int) {
s := make([]int, m)
last := m - 1
var rc func(int, int)
rc = func(i, next int) {
for j := next; j < n; j++ {
s[i] = j
if i == last {
fmt.Println(s)
} else {
rc(i+1, j+1)
}
}
return
}
rc(0, 0)
}
Seems to me that s is being reused by each rc call so you just need to ensure that when storing s into an [][]int you store its copy, so as to not overwrite its contents during the next iteration.
To copy a slice you can use append like this:
scopy := append([]int{}, s...)
https://play.golang.org/p/lggy5JFL0Z
package main
import (
"fmt"
)
func main() {
out := comb(5, 3)
fmt.Println(out)
}
func comb(n, m int) (out [][]int) {
s := make([]int, m)
last := m - 1
var rc func(int, int)
rc = func(i, next int) {
for j := next; j < n; j++ {
s[i] = j
if i == last {
out = append(out, append([]int{}, s...))
} else {
rc(i+1, j+1)
}
}
return
}
rc(0, 0)
return out
}
I am trying to implement the fizz buzz problem using maps in go lang. However, this code requires improvement in its working. It keeps on printing undesired and redundant results due to the for loop that iterates over the map. I tried a lot of solutions but failed. Is it feasible without using any help of a slice of keys?
package main
import "fmt"
func fizzbuzz(i int) {
myMap:= make(map[int]string)
myMap[3] = "fizz"
myMap[5] = "buzz"
myMap[15] = "fizzbuzz"
for k,v:= range myMap{
if i%k==0 {fmt.Printf("%v \n",v)
} else {fmt.Printf("%v \n",i)}
}
}
func main() {
for i:=1;i<10000;i++ {
fizzbuzz(i)
}
}
With a map
With your rule set, the entire for loop should be to decide if the i number is to be replaced with a word. But you emit a result in each iteration. At most one result should be emitted by the for. If i is not dividable by any of the keys, then i should be emitted.
Keys may be multiples of others (e.g. 15 = 3 * 5), and if the i number is dividable by such a key, we want to emit the word associated with the greatest key. So the for loop should not emit anything, because if you find a good key, there may be a greater one. So the loop should just find the greatest good key.
After the loop you can check if any good key was found, and if so, emit the word associated with it, else emit the number:
var rules = map[int]string{
3: "fizz",
5: "buzz",
15: "fizzbuzz",
}
func fizzbuzz(i int) {
max := -1
for k := range rules {
if i%k == 0 && k > max {
max = k
}
}
if max < 0 {
fmt.Println(i)
} else {
fmt.Println(rules[max])
}
}
func main() {
for i := 1; i < 100; i++ {
fizzbuzz(i)
}
}
Output (try it on the Go Playground):
1
2
fizz
4
buzz
fizz
7
8
fizz
buzz
11
fizz
13
14
fizzbuzz
16
17
fizz
19
buzz
fizz
...
With an ordered slice
You can get better performance if the rules are sorted by the keys descending, in which case you can check the keys in that order (greatest first), and then the first that qualifies will be the greatest. So you can emit the result immediately, and return.
If execution continues after the loop, we know no keys were good, we can emit the i number:
var rules = []struct {
n int
word string
}{
{15, "fizzbuzz"},
{5, "buzz"},
{3, "fizz"},
}
func fizzbuzz(i int) {
for _, rule := range rules {
if i%rule.n == 0 {
fmt.Println(rule.word)
return
}
}
fmt.Println(i)
}
Try this on the Go Playground.
General (excluding multiples from rules)
Although you started with a rule set where 15 = 3 * 5 was included in the rules, this should not be the case; you should only list 3 and 5, 15 should be implicit.
In this case, you have to check all the rules of course, because each good key should emit a word. And you have to remember if a good key was found, and only emit the i number otherwise.
This is how you can do it:
var rules = []struct {
n int
word string
}{
{3, "fizz"},
{5, "buzz"},
}
func fizzbuzz(i int) {
found := false
for _, rule := range rules {
if i%rule.n == 0 {
found = true
fmt.Print(rule.word)
}
}
if !found {
fmt.Print(i)
}
fmt.Println()
}
Try it on the Go Playground.
Note: in this solution you could also use a map instead of the slice; the reason why I used a slice is so that in case of multiple good keys the emitted words will always be in the same order (defined by increasing keys), as iteration order of keys in a map is not defined. For details, see Why can't Go iterate maps in insertion order?
As mentioned, the order of items in a map, is not deterministic in Go. Though here are some simple solutions:
func fizzbuzz(n int) {
for i := 1; i <= n; i++ {
switch {
case i%15 == 0:
println("fizzbuzz")
case i%5 == 0:
println(`buzz`)
case i%3 == 0:
println(`fizz`)
default:
println(i)
}
}
}
func fizzbuzzList(n int) []string {
var res []string
for i := 1; i <= n; i++ {
switch {
case i%15 == 0:
res = append(res, `fizzbuzz`)
case i%5 == 0:
res = append(res, `buzz`)
case i%3 == 0:
res = append(res, `fizz`)
default:
res = append(res, strconv.Itoa(i))
}
}
return res
}
func fizzbuzzLazy(n int) chan string {
var res = make(chan string)
go func() {
for i := 1; i <= n; i++ {
switch {
case i%15 == 0:
res <- `fizzbuzz`
case i%5 == 0:
res <- `buzz`
case i%3 == 0:
res <- `fizz`
default:
res <- strconv.Itoa(i)
}
}
close(res)
}()
return res
}
And usage:
fizzbuzz(20)
for _, v := range fizzbuzzList(20) {
println(v)
}
for v := range fizzbuzzLazy(20) {
println(v)
}
I am trying to create a function that could accept following
*struct
[]*struct
map[string]*struct
Here struct could be any struct not just a specific one.
Converting interface to *struct or []*struct is working fine.
But giving error for map.
After reflect it shows it is map[] but giving error when try to iterate over range.
Here is code
package main
import (
"fmt"
"reflect"
)
type Book struct {
ID int
Title string
Year int
}
func process(in interface{}, isSlice bool, isMap bool) {
v := reflect.ValueOf(in)
if isSlice {
for i := 0; i < v.Len(); i++ {
strct := v.Index(i).Interface()
//... proccess struct
}
return
}
if isMap {
fmt.Printf("Type: %v\n", v) // map[]
for _, s := range v { // Error: cannot range over v (type reflect.Value)
fmt.Printf("Value: %v\n", s.Interface())
}
}
}
func main() {
b := Book{}
b.Title = "Learn Go Language"
b.Year = 2014
m := make(map[string]*Book)
m["1"] = &b
process(m, false, true)
}
Is there any way to convert interface{} to map and iterate or get it's elements.
If the map value can be any type, then use reflect to iterate through the map:
if v.Kind() == reflect.Map {
for _, key := range v.MapKeys() {
strct := v.MapIndex(key)
fmt.Println(key.Interface(), strct.Interface())
}
}
playground example
If there's a small and known set of struct types, then a type switch can be used:
func process(in interface{}) {
switch v := in.(type) {
case map[string]*Book:
for s, b := range v {
// b has type *Book
fmt.Printf("%s: book=%v\n" s, b)
}
case map[string]*Author:
for s, a := range v {
// a has type *Author
fmt.Printf("%s: author=%v\n" s, a)
}
case []*Book:
for i, b := range v {
fmt.Printf("%d: book=%v\n" i, b)
}
case []*Author:
for i, a := range v {
fmt.Printf("%d: author=%v\n" i, a)
}
case *Book:
fmt.Ptintf("book=%v\n", v)
case *Author:
fmt.Printf("author=%v\n", v)
default:
// handle unknown type
}
}
You don't need reflect here. Try:
v, ok := in.(map[string]*Book)
if !ok {
// Can't assert, handle error.
}
for _, s := range v {
fmt.Printf("Value: %v\n", s)
}
Same goes for the rest of your function. It looks like you're using reflection when you would be better served by a type switch.
Alternatively, if you insist on using reflection here (which doesn't make a lot of sense) you can also use Value.MapKeys with the result from your ValueOf (see the answer https://stackoverflow.com/a/38186057/714501)
This may help:
b := []byte(`{"keyw":"value"}`)
var f interface{}
json.Unmarshal(b, &f)
myMap := f.(map[string]interface{})
fmt.Println(myMap)
Another way to convert an interface{} into a map with the package reflect is with MapRange.
I quote:
MapRange returns a range iterator for a map. It panics if v's Kind is
not Map.
Call Next to advance the iterator, and Key/Value to access each entry.
Next returns false when the iterator is exhausted. MapRange follows
the same iteration semantics as a range statement.
Example:
iter := reflect.ValueOf(m).MapRange()
for iter.Next() {
key := iter.Key().Interface()
value := iter.Value().Interface()
...
}
In functional programming likes Haskell, I can define function
add a b = a+b
Then add 3 will return a function that take one parameter and will return 3 + something
How can I do this in GO?
When I define a function that take more than one (say n) parameters, can I only give it one parameter and get another function that take n-1 parameters?
Update:
Sorry for the imprecise words in my original question.
I think my question should be asked as two qeustions:
Is there partial application in GO?
How GO do function curry?
Thanks TheOnly92 and Alex for solving my second question. However, I am also curious about the first question.
To extend on the previous answer, which allows you to take an arbitrary number of arguments:
package main
import (
"fmt"
)
func mkAdd(a int) func(...int) int {
return func(b... int) int {
for _, i := range b {
a += i
}
return a
}
}
func main() {
add2 := mkAdd(2)
add3 := mkAdd(3)
fmt.Println(add2(5,3), add3(6))
}
Perhaps something like
package main
import (
"fmt"
)
func mkAdd(a int) func(int) int {
return func(b int) int {
return a + b
}
}
func main() {
add2 := mkAdd(2)
add3 := mkAdd(3)
fmt.Println(add2(5), add3(6))
}
You can take it a step further by defining a function type and then adding a method to it.
package main
import "fmt"
type Add func(int, int) int
func (f Add) Apply(i int) func(int) int {
return func(j int) int {
return f(i, j)
}
}
func main() {
var add Add = func(i, j int) int { return i + j }
add3 := add.Apply(3)
fmt.Println("add 3 to 2:", add3(2))
}
You can even try with variadic functions:
package main
import "fmt"
type Multiply func(...int) int
func (f Multiply) Apply(i int) func(...int) int {
return func(values ...int) int {
values = append([]int{i}, values...)
return f(values...)
}
}
func main() {
var multiply Multiply = func(values ...int) int {
var total int = 1
for _, value := range values {
total *= value
}
return total
}
var times2 Multiply = multiply.Apply(2)
fmt.Println("times 2:", times2(3, 4), "(expect 24)")
// ... and you can even cascade (if assigned the Multiply type)
times6 := times2.Apply(3)
fmt.Println("times 6:", times6(2, 3, 5, 10), "(expect 1800)")
}
Hope this helps!
How to cast reflect.Value to its type?
type Cat struct {
Age int
}
cat := reflect.ValueOf(obj)
fmt.Println(cat.Type()) // Cat
fmt.Println(Cat(cat).Age) // doesn't compile
fmt.Println((cat.(Cat)).Age) // same
Thanks!
concreteCat,_ := reflect.ValueOf(cat).Interface().(Cat)
see http://golang.org/doc/articles/laws_of_reflection.html
fox example
type MyInt int
var x MyInt = 7
v := reflect.ValueOf(x)
y := v.Interface().(float64) // y will have type float64.
fmt.Println(y)
Ok, I found it
reflect.Value has a function Interface() that converts it to interface{}
This func auto-converts types as needed. It loads a config file values into a simple struct based on struct name and fields:
import (
"fmt"
toml "github.com/pelletier/go-toml"
"log"
"os"
"reflect"
)
func LoadConfig(configFileName string, configStruct interface{}) {
defer func() {
if r := recover(); r != nil {
fmt.Println("LoadConfig.Recovered: ", r)
}
}()
conf, err := toml.LoadFile(configFileName)
if err == nil {
v := reflect.ValueOf(configStruct)
typeOfS := v.Elem().Type()
sectionName := getTypeName(configStruct)
for i := 0; i < v.Elem().NumField(); i++ {
if v.Elem().Field(i).CanInterface() {
kName := conf.Get(sectionName + "." + typeOfS.Field(i).Name)
kValue := reflect.ValueOf(kName)
if (kValue.IsValid()) {
v.Elem().Field(i).Set(kValue.Convert(typeOfS.Field(i).Type))
}
}
}
} else {
fmt.Println("LoadConfig.Error: " + err.Error())
}
}
Seems the only way would be to do a switch statement similar to (code below) (also, something like the commented line would've-been nice though doesn't work (:()):
func valuesFromStruct (rawV interface{}) []interface{} {
v := reflect.ValueOf(rawV)
out := make([]interface{}, 0)
for i := 0; i < v.NumField(); i += 1 {
field := v.Field(i)
fieldType := field.Type()
// out = append(out, field.Interface().(reflect.PtrTo(fieldType)))
switch (fieldType.Name()) {
case "int64":
out = append(out, field.Interface().(int64))
break`enter code here`
case "float64":
out = append(out, field.Interface().(float64))
break
case "string":
out = append(out, field.Interface().(string))
break
// And all your other types (here) ...
default:
out = append(out, field.Interface())
break
}
}
return out
}
Cheers!