'How to modify a slice within for loop? [duplicate]

I've got a slice of articles in my reading list. Each Article has the attribute "FeedURL" that has the URL of the feed the article came from. When I unsubscribe from a feed, I want to be able to remove every Article that contains that Feed's URL.

type Article struct {
    FeedURL string
    URL     string // should be unique
    // ... more data
}

func unsubscribe(articleList []Article, url string) []Article {
   // how do I remove every Article from articleList that contains url?
}

func main() {
    myArticleList := []Article{
        Article{"http://blog.golang.org/feed.atom", "http://blog.golang.org/race-detector"},
        Article{"http://planet.python.org/rss20.xml", "http://archlinux.me/dusty/2013/06/29/creating-an-application-in-kivy-part-3/"},
        Article{"http://planet.python.org/rss20.xml", "http://feedproxy.google.com/~r/cubicweborg/~3/BncbP-ap0n0/2957378"},
        // ... much more examples
    }

    myArticleList = unsubscribe(myArticleList, "http://planet.python.org/rss20.xml")

    fmt.Printf("%+v", myArticleList)
}

What is the efficient way of solving this problem?

At first my code looked like this for unsubscribe:

func unsubscribe(articleList []Article, url string) []Article {
    for _, article := range articleList {
        if article.FeedURL == url {
            articleList = append(articleList[:i], articleList[i+1:]...)
        }
    }
    return articleList
}

But then I realized that this would change the slice and make the for loop unpredictable.

What is an efficient and pretty way to accomplish this?

go


Solution 1:[1]

PeterSO's answer is gets the job done, and with efficiency.

But, I might go with something simple like this

func unsubscribe(articleList []Article, url string) (filtered []Article) {
    filtered = articleList[:0] // optional.  reuses already-allocated memory.
    for _, article := range articleList {
        if article.FeedURL != url {
            filtered = append(filtered, article)
        }
    }
    return
}

which only takes about a two seconds to read, and comprehend.

The idea works fine with pointers to articles too and, like PeterSO said, if your Article struct is big, that may be a good thing to do.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1