doulu8341 2013-06-29 22:36
浏览 77
已采纳

如何在for循环中修改分片?

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?

  • 写回答

2条回答 默认 最新

  • doumengxue7371 2013-06-30 01:18
    关注

    To be efficient:

    • Use a slice of pointers to Articles, then we will be moving pointers to structures instead of structure values.
    • If the order of the Articles in the list is not important, use the unordered algorithm; it reduces pointer movement. Otherwise, use the ordered algorithm. In any case, minimize pointer movement.
    • Don't leave dangling pointers at the end of the list. The garbage collector will think they are still in use; it looks at the slice capacity not the slice length.
    • Minimize memory allocations.

    For example,

    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)
    }
    

    Output:

    [{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条)

报告相同问题?

悬赏问题

  • ¥15 HFSS 中的 H 场图与 MATLAB 中绘制的 B1 场 部分对应不上
  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?