I want to remove range of slice from slice like remove "A", "B" from "A" to "Z", but I want to make it efficient (I don't know why in Go but in Python we can use hashmap).
The code below is the closest I can get but there are edge cases I miss:
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"
CodePudding user response:
It's better (faster) to use a map to represent the items that are to be deleted. If there's N things in the original list, and M things that are in the to-be-deleted list, your code (once the bugs are fixed) would run in O(NM) time, whereas a map-based solution will run in O(N) time.
Here's example code:
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))
}
If you really need the to-be-deleted things to be a slice, you should convert the slice into a map first. Then the code is O(N M) time.
CodePudding user response:
What you need to do is check if each item in the original exists in the list of items to delete, and if not then you add it to the result:
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
}
You might also find Does Go have "if x in" construct similar to Python? informative.