Удаление нескольких значений из карты в Go одновременно в цикле
Я пытаюсь удалить несколько значений из моего map[string][]interface{}
Я использую strings.Split
функция, чтобы отделить каждое значение, которое я хочу удалить, а затем перебирая их.
Мне удалось получить его, чтобы я мог удалить значения индекса 0 и 1, однако, 1,2 будет удалить значение индекса 1, но ошибка в индексе 2.
Мне также удалось получить его, чтобы удалить одно значение
Мой мыслительный процесс состоял в том, что, если я смогу заставить его удалить только одно значение (любой индекс, который я ввожу, в том числе первый и последний индекс), то я мог бы использовать цикл для циклического прохождения и удаления остальных.
Все хранится в ниже:
package db
var DataStore map[string][]interface{}
Функция
func HandleDelete(w http.ResponseWriter, k, v string) {
Он принимает значение, которое вы хотите удалить в качестве параметра (и ключ, но это полностью функционально)
Блок кода, в котором находится проблема
Цикл начинается в конце фрагмента карты, поэтому, когда вы удаляете значение индекса 5, например, 4 все еще равно 4. Тогда как, если я пойду другим путем, если я удалю 5, 6 станет индексом 5. Таким образом, 5,6 удалено будет означать, что 5,7 удаляется.
for i := len(db.DataStore) - 1; i >= 0; i-- {
for _, idxvalue := range values {
val, err := strconv.Atoi(idxvalue)
if err != nil {
log.Fatal(err)
return
}
dbval := db.DataStore[k][val]
if i == val {
if len(db.DataStore[k])-1 == i { //the length goes 1,2,3,4... the index goes 0,1,2,3 - therefore length -1, would be 3 - deletes the last index value
db.DataStore[k] = db.DataStore[k][:i]
} else { //delete everything else
db.DataStore[k] = append(db.DataStore[k][:i], db.DataStore[k][i+1:]...)
}
//when you delete the last value in that key, delete the key.
/*if len(db.DataStore[k]) == 0 {
delete(db.DataStore, k)
}*/
fmt.Fprintf(w, "Key: %v, Value: %v was deleted successfully", k, dbval)
}
}
}
Я пробовал обе петли, как показано ниже:
for i := len(db.DataStore) - 1; i >= 0; i-- {
Конечно, причина того, что нижеприведенное не сработало, в том, что вы получаете длину до цикла (в теле функции), который не будет меняться после каждой итерации.
idx := len(db.DataStore) - 1
for i := idx; i >= 0; i-- {
Приведенный ниже код должен удалить введенный индекс (это работает с одним значением)
if len(db.DataStore[k])-1 == i { //the length goes 1,2,3,4... the index goes 0,1,2,3 - therefore length -1, would be 3 - deletes the last index value
db.DataStore[k] = db.DataStore[k][:i]
} else { //delete everything else
db.DataStore[k] = append(db.DataStore[k][:i], db.DataStore[k][i+1:]...)
}
Я ожидаю, что выход "2,1" удалит индексы 1 и 2, но на самом деле ввод заключается в том, что он просто удаляет индекс 1.
2 ответа
Например,
package main
import "fmt"
// Delete m k v elements indexed by d.
func deleteMKVD(m map[string][]interface{}, k string, d []int) {
v, ok := m[k]
if !ok {
return
}
for _, i := range d {
if 0 <= i && i < len(v) {
v[i] = nil
}
}
lw := 0
for i := range v {
if v[i] != nil {
lw++
}
}
if lw == 0 {
delete(m, k)
return
}
w := make([]interface{}, 0, lw)
for i := range v {
if v[i] != nil {
w = append(w, v[i])
}
}
m[k] = w
}
func main() {
m := map[string][]interface{}{
"k0": {"v0", "v1", "v2", "v3"},
}
fmt.Println(m)
deleteMKVD(m, "k0", []int{0, 3})
fmt.Println(m)
deleteMKVD(m, "k0", []int{1, 0})
fmt.Println(m)
}
Детская площадка: https://play.golang.org/p/biEAxthTaj8
Выход:
map[k0:[v0 v1 v2 v3]]
map[k0:[v1 v2]]
map[]
Я думаю, что ваша проблема на самом деле удалить элементы из массива с массивом индексов.
Простое решение здесь будет:
1) Найти все индексы с определенным k, сделать его массивом (vals [] int).
2) Сортировать этот массив по потомкам. и итерируйте этот массив для удаления 3) Затем итерируйте этот массив для удаления элементов.
Таким образом, каждый раз, когда вы удаляете элемент, он не затрагивает индексы других элементов. Это может быть не самым эффективным, но это было бы быстрое решение.
Кстати, я думаю for i := len(db.DataStore) - 1; i >= 0; i--
это не то, что вы хотите.
Если я правильно понимаю, этот код, кажется, гарантирует, что val является самым большим индексом в этих индексах.
Так что вместо того, чтобы писать i:=len(db.DataStore) - 1
, вам действительно нужно i:=len(db.DataStore[k])-1