1

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"
3
  • What do you mean by "efficient"? How large are those slice arguments, typically? Commented Mar 28, 2022 at 11:10
  • 1
    not too large but this function will run pretty often like 10k request for second Commented Mar 28, 2022 at 15:41
  • Then Paul's answer is likely the way to go. Commented Mar 28, 2022 at 15:43

2 Answers 2

3

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.