我的阅读清单中有一篇文章。每篇文章都有属性“FeedURL”,其中包含文章来源的网址。当我取消订阅Feed时,我希望能够删除包含Feed的网址的每篇文章。
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)
}
解决这个问题的有效方法是什么?
首先,我的代码看起来像是取消订阅:
func unsubscribe(articleList []Article, url string) []Article {
for _, article := range articleList {
if article.FeedURL == url {
articleList = append(articleList[:i], articleList[i+1:]...)
}
}
return articleList
}
但后来我意识到这会改变切片并使for循环变得不可预测。
实现这一目标的有效而美观的方法是什么?
答案 0 :(得分:5)
要有效率:
例如,
package main
import "fmt"
type Article struct {
FeedURL string
URL string // should be unique
// ... more data
}
// Remove every Article from an articleList that contains url without preserving order.
func unsubscribeUnordered(a []*Article, url string) []*Article {
for i := 0; i < len(a); i++ {
if a[i].FeedURL == url {
a[len(a)-1], a[i], a = nil, a[len(a)-1], a[:len(a)-1]
i--
}
}
return a
}
// Remove every Article from an articleList that contains url while preserving order.
func unsubscribeOrdered(a []*Article, url string) []*Article {
j := 0
for i := 0; i < len(a); i++ {
if a[i].FeedURL == url {
continue
}
if i != j {
a[j] = a[i]
}
j++
}
for k := j; k < len(a); k++ {
a[k] = nil
}
return a[:j]
}
func NewArticleList() []*Article {
return []*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
}
}
func PrintArticleList(a []*Article) {
fmt.Print("[")
for _, e := range a {
fmt.Printf("%+v", *e)
}
fmt.Println("]")
}
func main() {
PrintArticleList(NewArticleList())
ao := unsubscribeOrdered(NewArticleList(), "http://planet.python.org/rss20.xml")
PrintArticleList(ao)
auo := unsubscribeUnordered(NewArticleList(), "http://planet.python.org/rss20.xml")
PrintArticleList(auo)
}
输出:
[{FeedURL:http://blog.golang.org/feed.atom URL:http://blog.golang.org/race-detector}{FeedURL:http://planet.python.org/rss20.xml URL:http://archlinux.me/dusty/2013/06/29/creating-an-application-in-kivy-part-3/}{FeedURL:http://planet.python.org/rss20.xml URL:http://feedproxy.google.com/~r/cubicweborg/~3/BncbP-ap0n0/2957378}]
[{FeedURL:http://blog.golang.org/feed.atom URL:http://blog.golang.org/race-detector}]
[{FeedURL:http://blog.golang.org/feed.atom URL:http://blog.golang.org/race-detector}]
答案 1 :(得分:0)
PeterSO的答案是完成工作,并且效率很高。
但是,我可能会选择像这样简单的东西
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
}
只需要大约两秒钟的时间来阅读和理解。
这个想法也适用于指向文章的指针,就像PeterSO所说,如果你的文章结构很大,这可能是件好事。