I want to iterate over this :
*list.List
How can I do it?
func Foo(key string, values *list.List) string {
...
//I want to iterate and get value from "values"
}
this Foo is being called like this:
kvs := make(map[string]*list.List)
res := Foo(k, kvs[k]) //k is string
Thanks!
Check the example # http://golang.org/pkg/container/list/ :
func Foo(key string, vl *list.List) string {
for e := l.Front(); e != nil; e = e.Next() {
v := e.Value
}
return ""
}
//edit : check Create a Golang map of Lists
Related
I'm creating a map of structs to hold different information. A sample struct I am using is:
type Test struct{
Value1 string
Value2 string
Value3 string
Value4 string
}
func main() {
testMap := make(map[string]*Test) //using a pointer to map
func2(testMap)
//pass map to another function for more additions.
}
func func2 (testMap map[string]*Test) {
a, b := getVal(); //get some random values
res := concat(a,b) //basically create a string key based on values a and b
testMap[res].value1 = a //****
testMap[res].value2 = b
//do something else
testMap[res].value3 = "hello"
}
I'm basically trying to create a map and add values to it as I get them, but im getting a invalid memory address or nil pointer dereference error on **** line (see code for ***).
Try:
func func2 (testMap map[string]*Test) {
a, b := getVal(); //get some random values
res := concat(a,b) //basically create a string key based on values a and b
testMap[res] = &Test{
Value1: a,
Value2: b,
Value3: "string",
}
}
Or if you want to create the object first, then populate the value, try
func func2 (testMap map[string]*Test) {
a, b := getVal(); //get some random values
res := concat(a,b) //basically create a string key based on values a and b
testMap[res] = &Test{}
testMap[res].value1 = a //****
testMap[res].value2 = b
//do something else
testMap[res].value3 = "hello"
}
I am trying to compare these two interfaces together as a function. It is working as far as I am concerned. I am sending a struct in A interface{} and map[string]interface{} in B, having the same values but when being compared with reflect they are not resulting to be the same. I would like to be able to convert the map[string]interface{} into a struct interface inside this function so that my tests can get shorter. I have tried using https://github.com/mitchellh/copystructure, but does not work inside this function.(from outside it works though:
var m map[string]interface{}
var something StructType
err := mapstructure.Decode(m, &something)
if err....
and then i send the something in the B interface)
below is the function to compare the interfaces. You can copy and paste and see how it works for yourself
package main
import (
"log"
"reflect"
)
type Something struct {
Name string
Age int
Male bool
Cars []string
}
func main() {
var s Something
s.Name = "joe"
s.Male = true
s.Age = 20
s.Cars = []string{"Fordd", "Chevy", "Mazda"}
m := make(map[string]interface{})
m["Name"] = "joe"
m["Male"] = true
m["Age"] = 20
m["Cars"] = []string{"Fordd", "Chevy", "Mazda"}
//with map[string]interface{} although the same values it does not work
log.Println("Are these the same: ", CompareData(s, m))
//with struct of same type it works
var s2 Something
s2.Name = "joe"
s2.Male = true
s2.Age = 20
s2.Cars = []string{"Fordd", "Chevy", "Mazda"}
log.Println("Are these the same: ", CompareData(s, s2))
}
func CompareData(A interface{}, B interface{}) bool {
a := reflect.ValueOf(A)
b := reflect.ValueOf(B)
akind := a.Kind().String()
bkind := a.Kind().String()
if akind == "slice" && bkind == "slice" {
for i := 0; i < a.Len(); i++ {
// log.Println("they are sliced")
CompareData(a.Index(i).Interface(), b.Index(i).Interface())
// log.Println("\n", a.Index(i).Interface(), "\n", b.Index(i).Interface())
}
// t.Fatal("this is a slice you need to iterate over the values")
} else {
// log.Println("\n\n", A, "\n", B)
if !reflect.DeepEqual(a.Interface(), b.Interface()) {
log.Println("These should be equal\nSuccessData:\t", a.Interface(), "\nData:\t\t", b.Interface())
return false
}
// log.Println("\nA:\t", A, "\nB:\t", B)
}
return true
}
I'm looking for the go equivalent of something like the below python snippet
indexes = [0,4]
nestedArray = [[1,2,3,4,5],[6,7,8]] # could be [][][]string, [][][][]float.. etc
def getNestedIndex(nestedArray, indexes):
curr = nestedArray
while indexes {
curr = nestedArray[indexes.pop(0)]
}
return curr # should be 5
I tried something like this
func nestedArrayIndex(slice []interface{}, indexes []int) interface{} {
if len(indexes) == 1 {
return slice[indexes[0]]
}
var newSlice []interface{}
newSlice = slice[indexes[0]]
return nestedArrayIndex(newSlice, indexes[1:])
}
but two things occur here - []Type != []interface{} and [][]..Type definitely won't work here.
Wondering if there's a way to achieve this in go?
You can do that with reflect. reflect.Value has a method Index for getting the item of the index in the slice underlying the Value.
func nestedArrayIndex(slice interface{}, indexes []int) interface{} {
v := reflect.ValueOf(slice)
for _, i := range indexes {
v = v.Index(i)
}
return v.Interface()
}
Playground: https://play.golang.org/p/Tmdomx18qPg
I'm writing a function in go to remove duplicate characters in a string. Here is my approach. When I run the following test, why do I get this error? I'm new to Go and used to more dynamic languages like Ruby/Python.
panic: assignment to entry in nil map [recovered]
panic: assignment to entry in nil map
source.go
func removeDuplicate(s string) string {
var m map[string]int
var c_string []string = strings.Split(s, "")
for i :=0; i < len(c_string); i++ {
m[c_string[i]] = 0
}
for i :=0; i < len(c_string); i++ {
m[c_string[i]] = m[c_string[i]] + 1
}
var (
result string = ""
)
for i :=0; i < len(c_string); i++ {
if m[c_string[i]] < 1 {
result = result + c_string[i]
}
}
return result
}
source_test.go
func TestRemoveDuplicateChars(t *testing.T) {
got := removeDuplicateChars("abbcde")
if got != "abcde" {
t.Fatalf("removeDuplicateChars fails")
}
}
Because you haven't actually initilize/allocated m, you've only declared it. Make this; var m map[string]int into m := map[string]int{}.
Which does initilization and assignment both in the same statement. You could also add another line m = make(map[string]int) which would prevent the error though I personally prefer the compacted syntax.
fyi your code is barfing on this line; m[c_string[i]] = 0, the error message should make sense when combining that with the information above.
How can i do this simplified in Golang
var planningDate string
date, ok := data["planningDate"]
if !ok {
planningDate = util.TimeStamp()
} else {
planningDate = date
}
Thanx
I don't see any way to do this in a single line, as there is no ternary operator in Go. You cannot use | either as operands are not numbers. However, here is a solution in three lines (assuming date was just a temporary variable):
planningDate, ok := data["planningDate"]
if !ok {
planningDate = util.TimeStamp()
}
You can do something like:
func T(exp bool, a, b interface{}) interface{} {
if exp {
return a
}
return b
}
and use it whenever you want, like a ternary-operator:
planningDate = T((ok), date, util.TimeStamp())