英文:
Golang: map with multiple values per key
问题
func ParseportsFromFile(file string) (map[string][]string, error) {
buf, err := ioutil.ReadFile(file)
if err != nil {
return nil, err
}
ret := make(map[string][]string)
rows := strings.Split(string(buf), "\n")
for _, row := range rows {
kvs := strings.SplitN(row, "=", 2)
if len(kvs) == 2 {
key := strings.TrimSpace(kvs[0])
value := strings.TrimSpace(kvs[1])
ret[key] = append(ret[key], value)
}
}
return ret, nil
}
这个函数允许我读取一个文件,文件内容如下:
user1=123
user1=321
user2=124
然而,返回的数据是:
map[user1:[321] user2:[124]]
这意味着user1=123
被user1=321
覆盖了。如何避免这种情况发生?如何创建一个类似于map[user1:[123,321], user2:124]
的数组,以避免一个项目覆盖另一个项目?
英文:
func ParseportsFromFile(file string) (map[string]string, error) {
buf, err := ioutil.ReadFile(file)
if err != nil {
return nil, err
}
ret := [make(map[string]string)]
rows := strings.Split(string(buf), "\n")
for _, row := range rows {
kvs := strings.SplitN(row, "=", 2)
if len(kvs) == 2 {
ret[strings.TrimSpace(kvs[0])] = strings.TrimSpace(kvs[1])
}
}
return ret, nil
}
This function allows me to read a file like that :
user1=123
user1=321
user2=124
However, the data return is
map[user1:321 user2:124]
So that mean user1=123 has been overwritten with user1=321
How to avoid that ?
How to create an array like
map[user1:[123,321], user2: 124]
to avoid an item to overwrite another ?
答案1
得分: 5
由于Go语言是强类型的,所以将其立即转换为切片的映射可能更容易。例如,可以参考http.Header类型。在设计时,他们也面临着同样的问题。
在你的情况下,代码可能如下所示:
result := make(map[string][]string)
for _, row := range rows {
parts := strings.Split(row, "=")
key := parts[0]
value := parts[1]
result[key] = append(result[key], value)
}
https://go.dev/play/p/5uRH-aQmATR
否则,你需要使用interface{}
(任意类型),这样你就可以同时拥有string
和[]string
,但是实现这个逻辑会更复杂,而且使用起来也更复杂,因为你总是需要检查它的类型并进行类型断言等操作。总的来说,我不建议这样做。
英文:
Since go is strongly typed, it would be easier to make it right away a map of slices. See the http.Header type, for example. They had the same problem to solve when designing it.
In your case, this could look something like this:
result := make(map[string][]string)
for _, row := range rows {
parts := strings.Split(row, "=")
key := parts[0]
value := parts[1]
result[key] = append(result[key], value)
}
https://go.dev/play/p/5uRH-aQmATR
Otherwise, you need to use interface{}
(any) so you can have both, string
and []string
, but the logic to get that done would be more complex, and using it would be also more complex since you always need to check what it is and do type assertion and so on. After all, I would not recommend it.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论