In .Each func how “return” #13

Closed
mejinke opened this Issue May 24, 2013 · 4 comments

Comments

Projects
None yet
2 participants

mejinke commented May 24, 2013

doc.Find("dl[class='brand_tree'] dd ul li").Each(func(index int, s *goquery.Selection) {
brandLiId, exists := s.Attr("id")
if exists == false {
return // End "Each" ?
}

//......
})

Owner

mna commented May 24, 2013

You're right, this is not consistent with jQuery, which allows breaking out of the Each loop. I'll think about a way to fix this without breaking compatibility (the func parameter needs a different signature, so this is a problem).

As for your specific case, in the meantime, you can simply keep a flag (even though it will not break the loop). Or use a selector string to find this condition (untested):

sel := doc.Find("dl[class='brand_tree'] dd ul").Has("li:not([id])")
// if sel.Length() > 0, then your condition is met

mejinke commented May 24, 2013

selections := doc.Find("ul[class='carinfo_ul'] li table tr")
            if selections.Size() == 0 {
                baojia.AddError("autohome", "0", url, "没有解析到任何内容")
                return
            }
            selections.Each(func(index int, s *goquery.Selection) {
                tdSelection := s.Find("td")
                if tdSelection.Size() != 7 {
                    return
                }
                autoNameSelection := tdSelection.Eq(1).Find("a")
                if autoNameSelection.Size() != 1 {
                    baojia.AddError("autohome", "0", url, "errr")
                    return
                }
                autoName := autoNameSelection.Text()


                baojiaUrl, exists := autoNameSelection.Attr("href")
                if !exists {
                    baojia.AddError("autohome", "0", url, "无法获取到报价URL")
                    return
                }
                baojiaUrl = "http://dealer.autohome.com.cn" + baojiaUrl


                prices := tdSelection.Eq(2).Find("a[class='fontred linkred']").Text()
                prices = strings.Replace(prices, "", "", 1)
                prices = strings.Replace(prices, "预售价:", "", 1)
                tmp := strings.Split(prices, "-")
                prices = tmp[0]
                newPrice, err := strconv.ParseFloat(prices, 64)
                if err != nil {
                    baojia.AddError("autohome", "0", baojiaUrl, "报价("+prices+")转换float64失败")
                    return
                }

                tmp = strings.Split(baojiaUrl, "spec_")
                if len(tmp) != 2 {
                    baojia.AddError("autohome", "0", baojiaUrl, "无法解析到车型ID")
                    return
                }
                autoTypeId := strings.Replace(tmp[1], ".html", "", 1)
                newAutoTypeId, err := strconv.Atoi(autoTypeId)
                if err != nil {
                    baojia.AddError("autohome", "0", baojiaUrl, "车型ID("+autoTypeId+")转换int失败")
                    return
                }
                             //save data....
            })

You can see a lot of time need return, according to the way you said, it seems unreasonable! Is that right ?

mejinke commented May 24, 2013

use "return" can reduce the frequent nested if else , but I do not know this right.

Owner

mna commented May 24, 2013

In fact I have added EachWithBreak() right now, it takes a func(int, *Selection) bool as argument. Let me push it to github in a second, you will be able to break out of the loop with a return false.

@mna mna closed this in 948b88c May 24, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment