Golang中如何从自定义类型MAP中删除指定KEY的VALUE
Golang中如何从自定义类型MAP中删除指定KEY的VALUE
我有一个类型为 []keyValue 的映射如下:
var data map[string][]keyValue
下面的结构体是上述映射中的自定义切片类型。这样设计的目的是允许在映射中存储多种数据类型。每个键只存在一个实例,但可以有多个值和数据类型。
type keyValue struct {
String string
Integer int
IntegerOK bool
Float float64
FloatOK bool
Boolean bool
BooleanOK bool
}
我希望能够从上述映射中删除值…例如: 键:DOG 值:zeus 键:DOG 值:true
如果我想删除 true,应该使用什么最佳代码?
在更新代码以接受映射中的多种数据类型之前,以下代码可以正常工作…通过遍历特定键,然后获取 URL 中输入内容的索引值并简单地将其移出
func deleteKeyValue(w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
k := params["key"]
v := params["value"]
//删除值
if v != "" {
if _, ok := data[k]; ok {
for i := range data[k] {
data[k] = append(data[k][:i], data[k][i+1:]...)
}
fmt.Fprintf(w, "KEY: %v, VALUE: %v has been deleted from the Key-Value store", k, v)
} else {
fmt.Fprintf(w, "That Key-Value pairing doesn't exist in the Key-Value store")
}
现在当上述代码运行时,使用映射上的新数据类型,我收到以下错误:
2019/01/09 19:59:03 http: panic serving [::1]:53122: runtime error: slice bounds out of range goroutine 4 [running]: net/http.(*conn).serve.func1(0xc000110000) C:/Go/src/net/http/server.go:1746 +0xd7
更多关于Golang中如何从自定义类型MAP中删除指定KEY的VALUE的实战教程也可以访问 https://www.itying.com/category-94-b0.html
非常感谢您的帮助!很高兴您理解了我的问题,您给出的示例正是我需要的!感谢您的帮助。
更多关于Golang中如何从自定义类型MAP中删除指定KEY的VALUE的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
如果我理解正确的话,你需要检查遍历中的类型和值,并在匹配时进行删除,类似这样(为简洁起见我省略了类型转换):
shouldDelete := false
for i, keyValue := range data[k] {
if keyValue.IntegerOk {
//将v转换为int并比较
//如果匹配,将shouldDelete设为true
} else if keyValue.FloatOk {
//将v转换为float并比较
//如果匹配,将shouldDelete设为true
} else if keyValue.BooleanOk {
//将v转换为bool并比较
//如果匹配,将shouldDelete设为true
}
if shouldDelete {
if len(data[k]) - 1 == i {
data[k] = data[k][:i]
} else {
data[k] = append(data[k][:i], data[k][i+1:]...)
}
fmt.Fprintf(w, "KEY: %v, VALUE: %v has been deleted from the Key-Value store", k, v)
break
}
}
if !shouldDelete {
//没有匹配值的元素,打印提示信息
fmt.Fprintf(w, "KEY: %v, VALUE: %v wasn't found in the Key-Value store", k, v)
}
我假设Ok字段表示值的类型,并且每个实例只允许一个为真。如果不是这种情况,请相应调整。
这段代码还添加了一个检查,看匹配是否发生在切片的最后一个元素上,如果是这种情况,你只需要从开始到倒数第二个元素进行切片。如果不检查且确实是最后一个元素匹配,data[k][i+1:] 将会panic,因为你超出了切片的边界,即 data[k][i+1] 超出了切片的末尾。
在Go语言中,从自定义类型映射中删除指定键的值时,需要正确处理切片操作以避免索引越界错误。以下是修复后的代码示例:
func deleteKeyValue(w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
k := params["key"]
v := params["value"]
if v != "" {
if values, ok := data[k]; ok {
// 创建新切片保存保留的值
var newValues []keyValue
// 遍历所有值,只保留不匹配的值
for _, kv := range values {
shouldDelete := false
// 检查各种数据类型的值是否匹配
if kv.String == v {
shouldDelete = true
} else if kv.BooleanOK && strconv.FormatBool(kv.Boolean) == v {
shouldDelete = true
} else if kv.IntegerOK && strconv.Itoa(kv.Integer) == v {
shouldDelete = true
} else if kv.FloatOK && strconv.FormatFloat(kv.Float, 'f', -1, 64) == v {
shouldDelete = true
}
if !shouldDelete {
newValues = append(newValues, kv)
}
}
// 更新映射中的值
if len(newValues) == 0 {
delete(data, k)
} else {
data[k] = newValues
}
fmt.Fprintf(w, "KEY: %v, VALUE: %v has been deleted from the Key-Value store", k, v)
} else {
fmt.Fprintf(w, "That Key-Value pairing doesn't exist in the Key-Value store")
}
}
}
或者使用更简洁的索引删除方法:
func deleteKeyValue(w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
k := params["key"]
v := params["value"]
if v != "" {
if values, ok := data[k]; ok {
for i := 0; i < len(values); i++ {
kv := values[i]
shouldDelete := false
if kv.String == v {
shouldDelete = true
} else if kv.BooleanOK && strconv.FormatBool(kv.Boolean) == v {
shouldDelete = true
} else if kv.IntegerOK && strconv.Itoa(kv.Integer) == v {
shouldDelete = true
} else if kv.FloatOK && strconv.FormatFloat(kv.Float, 'f', -1, 64) == v {
shouldDelete = true
}
if shouldDelete {
// 从切片中删除元素
values = append(values[:i], values[i+1:]...)
i-- // 调整索引,因为切片长度减少了
}
}
// 更新映射
if len(values) == 0 {
delete(data, k)
} else {
data[k] = values
}
fmt.Fprintf(w, "KEY: %v, VALUE: %v has been deleted from the Key-Value store", k, v)
} else {
fmt.Fprintf(w, "That Key-Value pairing doesn't exist in the Key-Value store")
}
}
}
原代码的问题在于使用了错误的切片删除逻辑。data[k] = append(data[k][:i], data[k][i+1:]...) 在循环中会破坏切片结构,导致索引越界。修复后的代码正确处理了各种数据类型的值比较和切片删除操作。

