Удаление нескольких значений из карты в Go одновременно в цикле - PullRequest
2 голосов
/ 24 марта 2019

Я пытаюсь удалить несколько значений из моего 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 ]

1 голос
/ 25 марта 2019

Например,

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[]
0 голосов
/ 25 марта 2019

Я думаю, что ваша проблема на самом деле состоит в том, чтобы удалить элементы из массива с массивом индексов.
Здесь легко исправить:
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

...