英文:
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)
答案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, ",")
if i < 0 {
log.Fatal("bad line", 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("phone number is: %q \n", callDetails[1])
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论