Can't get appropriate output while concating string with nested map

125 Views Asked by At

I'm new with galang and I want to concat string with nested map. Below is the dummy code given, point out my mistake. Thanks in advance

    import (
    "fmt"
    "strconv"
    )

    func main() {
    str := "Hello @John martin #sosos &Hi @William "
    var key string = ""
    var ku int = 0
    var kh int = 0
    var kg int = 0
    var id string
    var col string 
    var retMap = make(map[string]map[string]string)
    retMap[key] = make(map[string]string)    
    for i := 0; i < len(str); i++ {
      //fmt.Println(string(str[i]), " >> ", str[i])
      if str[i] == 64 || str[i] == 35 || str[i] == 38 {
        if str[i] == 64 {
          ku++
          key = "user"
          id = strconv.Itoa(ku)
      } else if str[i] == 35 {
        kh++
        key = "hashTag"
        id = strconv.Itoa(kh)
      } else {
        kg++
        key = "group"
        id = strconv.Itoa(kg)
      }
      retMap[key] = make(map[string]string) // If not assign here then it gives runtime error "panic: assignment to entry in nil map"
      for j := i + 1; j < len(str); j++ {
        col = col + string(str[j])
        if str[j] == 32 {
          j = len(str) - 1
          retMap[key][id] = retMap[key][id] + col
          col = " "
        }
      }
    }
 }
 fmt.Println("Final String ",retMap)
}

Output : Final String map[group:map[1: Hi ] user:map[2: William ] hashTag:map[1: sosos ]]

Expected Output :

Final String map[group:map[1: Hi ] user:map[1: John, 2: William ] hashTag:map[1: sosos ]]

It might be duplicate of

Runtime error: "assignment to entry in nil map"

Runtime error: assignment to entry in nil map

but not understand kindly provide me a solution. Thanks

1

There are 1 best solutions below

1
JesusTinoco On BEST ANSWER

The issue is that you are initializing the nested map of "key" in each called, so it always overrides the previous data.

So just changing your line

retMap[key] = make(map[string]string) // If not assign here then it gives runtime error "panic: assignment to entry in nil map"

to the below should make your code work:

=_, ok := retMap[key]
if !ok {
    retMap[key] = make(map[string]string)
}

I'm just checking the existence of a value stored for "key", and initialize a new map if it doesn't exist.


Updated:

I also rewrote your code to use some built-in functions that Go provide with, as strings.Split or strings.Trim* functions. It could be helpful.

package main

import (
    "fmt"
    "strconv"
    "strings"
)

const str = "Hello @John martin #sosos &Hi @William "

func main() {
    retMap := make(map[string]map[string]string)
    retMap["group"] = make(map[string]string)
    retMap["user"] = make(map[string]string)
    retMap["hashTag"] = make(map[string]string)
    list := strings.Split(strings.TrimSpace(str), " ")

    for _, value := range list {
        firstCharacter := string(value[0])
        if firstCharacter == "@" {
            retMap["user"][strconv.Itoa(len(retMap["user"])+1)] = strings.TrimLeft(value, "@")
        } else if firstCharacter == "&" {
            retMap["group"][strconv.Itoa(len(retMap["group"])+1)] = strings.TrimLeft(value, "&")
        } else if firstCharacter == "#" {
            retMap["hashTag"][strconv.Itoa(len(retMap["hashTag"])+1)] = strings.TrimLeft(value, "#")
        }
    }

    fmt.Println("Final String ", retMap)
}