从切片中删除字符串切片

Remove slice of string from slice

我想从切片中删除切片范围,例如从“A”到“Z”中删除“A”、“B”,但我想让它更有效率(我不知道为什么在 Go 中,但在Python 我们可以使用 hashmap)。

下面的代码是我能得到的最接近的代码,但我错过了一些边缘情况:

func removeString(listOri []string, targetDelete []string) []string {
    newitems := []string{}
    for i := range listOri {
        for j := range targetDelete {
            if listOri [i] != targetDelete[j] {
                newitems = append(newitems, listOri [i])
            }
        }
    }

    return newitems
}

listOriginal := []string{"A", "B", "C", "D"}
listDelete := []string{"A", "B"}
listNew := removeString(listOriginal, listDelete)
result = "A","B","C","C","D","D"

您需要做的是检查原始项目中的每一项是否存在于要删除的项目列表中,如果不存在,则然后将其添加到结果中:

func removeString(listOri []string, targetDelete []string) []string {
    newitems := []string{}
    var found bool

    for i := range listOri {
        found = false
        for j := range targetDelete {
            if listOri[i] == targetDelete[j] {
                found = true
                break
            }
        }
        if !found {
            newitems = append(newitems, listOri[i])
        }
    }

    return newitems
}

您可能还会发现 Does Go have "if x in" construct similar to Python? 有用。

最好(更快)使用地图来表示要删除的项目。如果原始列表中有 N 个东西,to-be-deleted 列表中有 M 个东西,你的代码(一旦错误被修复)将在 O(NM) 时间内 运行,而 map-based 解决方案将在 O(N) 时间内 运行。

示例代码如下:

package main

import "fmt"

func filter(src []string, del map[string]bool) []string {
    var dst []string
    for _, s := range src {
        if !del[s] {
            dst = append(dst, s)
        }
    }
    return dst
}

func main() {
    src := []string{"A", "B", "C", "D"}
    del := map[string]bool{"A": true, "B": true}
    fmt.Println(filter(src, del))
}

如果你真的需要to-be-deleted的东西是切片,你应该先把切片转换成地图。那么代码就是O(N+M)次了。