Golang map[string]float where float is getting overwirtten instead of adding to the existing value present for the key

huangapple go评论79阅读模式
英文:

Golang map[string]float where float is getting overwirtten instead of adding to the existing value present for the key

问题

我有一个字符串,如下所示:

00:01:07,400-234-090
00:05:01,701-080-080
00:05:00,400-234-090

其中右侧是电话号码,左侧是以hh:mm:ss格式表示的通话持续时间。我想将其拆分并放入一个map[string]float64中。首先,我会通过逗号,拆分字符串,然后再通过冒号:拆分左侧部分。然后,我会将通话持续时间转换为time.Duration并转换为分钟。到这里都没问题。

现在我想将其放入一个map中,我期望如果右侧的电话号码已经存在于map中,它会将float64值添加到该键的现有值上。然而,事实并非如此,似乎在map中出现了相同的键两次。

以下是我的代码:

phoneBill := `00:01:07,400-234-090
              00:05:01,701-080-080
              00:05:00,400-234-090`

callLog := strings.Split(phoneBill, "\n")

mapDetails := make(map[string]float64)
for _, v := range callLog {
    callDetails := strings.Split(strings.TrimSpace(v), ",")
    timeDetails := strings.Split(strings.TrimSpace(callDetails[0]), ":")
    durationString := strings.TrimSpace(timeDetails[0]) + "h" + strings.TrimSpace(timeDetails[1]) + "m" + strings.TrimSpace(timeDetails[2]) + "s"

    t, _ := time.ParseDuration(durationString)

    total := t.Minutes()
    fmt.Printf("电话号码是:%v \n", callDetails[1])
    fmt.Printf("通话持续时间(分钟):%v \n", total)

    if v, found := mapDetails[callDetails[1]]; found {
        total += v
        fmt.Println("总计:", total)
    }
    mapDetails[callDetails[1]] = total
}
fmt.Println("map中的值为:", mapDetails)

你可以在这里运行代码:https://go.dev/play/p/fLcEDbgQ-7q

英文:

I have a string like so
00:01:07,400-234-090
00:05:01, 701-080-080
00:05:00, 400-234-090

where the on the right side is the phone number and on the left is the duration of the call in hh:mm:ss format. I am trying to put this in a map[string]float64 by splitting the string first on "," and the split the left side on ":". Then make a Duration from the duration of the call and convert in to minutes. It works fine till this.
Now I am trying to put this in a map, I expected that if the key which is the phone number on the right is already present in the map then it will just add the float64 value to the existing value of the key. However, that is not the case, it seems to be having the same key twice in the map.

Here is my code:

phoneBill := `00:01:07,400-234-090
	      00:05:01, 701-080-080
	      00:05:00, 400-234-090`

callLog := strings.Split(phoneBill, "\n")

mapDetails := make(map[string]float64)
for _, v := range callLog {
	callDetails := strings.Split(strings.TrimSpace(v), ",")
	timeDetails := strings.Split(strings.TrimSpace(callDetails[0]), ":")
	durationString := strings.TrimSpace(timeDetails[0]) + "h" + strings.TrimSpace(timeDetails[1]) + "m" + strings.TrimSpace(timeDetails[2]) + "s"

	t, _ := time.ParseDuration(durationString)

	total := t.Minutes()
	fmt.Printf("phone number is: %v \n", callDetails[1])
	fmt.Printf("duration of call in minutes is %v \n", total)

	if v, found := mapDetails[callDetails[1]]; found {
		total += v
		fmt.Println("total is :v", total)
	}
	mapDetails[(callDetails[1])] = total

}
fmt.Println("Values in map are: %v", mapDetails)

https://go.dev/play/p/fLcEDbgQ-7q

答案1

得分: 2

修复代码中对持续时间和数字进行修剪的问题。当前的代码不能处理逗号前后的空格。

i := strings.Index(v, ",")
if i < 0 {
    log.Fatal("bad line", v)
}
dur := strings.TrimSpace(v[:i])
num := strings.TrimSpace(v[i+1:])

利用映射在键缺失时返回零值的特性,可以简化更新映射的代码如下:

mapDetails[num] += total

在调试解析字符串的代码时,通过使用%q打印可以将空格可见化。原始程序中的错误可以通过以下方式更容易地发现:

fmt.Printf("phone number is: %q \n", callDetails[1])

Playground上运行代码。

英文:

Fix by trimming spaces on the duration and the number. The current code does not handle spaces before or after the comma.

	i := strings.Index(v, &quot;,&quot;)
	if i &lt; 0 {
		log.Fatal(&quot;bad line&quot;, v)
	}
	dur := strings.TrimSpace(v[:i])
	num := strings.TrimSpace(v[i+1:])

Taking advantage of the fact that maps return the zero value for missing keys, the code to update the map can be simplified to the following.

	mapDetails[num] += total

Run the code on the playground.

When debugging code that parses strings, it's helpful to make whitespace visible by printing with %q. The bug in the original program is more visible with:

	fmt.Printf(&quot;phone number is: %q \n&quot;, callDetails[1])

huangapple
  • 本文由 发表于 2022年2月26日 13:27:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/71274301.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定