Почему словарь-член в этом коде f # всегда пуст? - PullRequest
0 голосов
/ 29 июля 2011

Я хочу очистить страницу для всех URL-адресов и поместить их в словарь.Я создал класс со словарем.Но я не могу добавить в него элементы.

type crawler =

     new()= {}
     member this.urls  = new Dictionary<string,string>()
     member this.start (url : string)=
        let hw = new HtmlWeb()
        let doc = hw.Load(url)
        let docNode = doc.DocumentNode
        let links = docNode.SelectNodes(".//a")

        for aLink in links do
            let href = aLink.GetAttributeValue("href"," ")
            if href.StartsWith("http://")  && href.EndsWith(".html") then
              this.urls.Add(href, href)

Почему URL-адрес словаря пуст?

Ответы [ 2 ]

5 голосов
/ 29 июля 2011

, поскольку URL-адреса здесь - это свойство, которое возвращает новый словарь при каждом вызове.

type Crawler() =  
    let urls = new Dictionary<string,string>()
    member this.Urls  = urls
    member this.Start (url : string)=        
        let hw = new HtmlWeb()        
        let doc = hw.Load(url)        
        let docNode = doc.DocumentNode        
        let links = docNode.SelectNodes(".//a")        
        for aLink in links do            
            let href = aLink.GetAttributeValue("href"," ")            
            if href.StartsWith("http://")  && href.EndsWith(".html") then              
                urls.Add(href, href)
3 голосов
/ 29 июля 2011

Это был не ваш вопрос, но если вы заинтересованы в более функциональном подходе, вот один из способов сделать это:

type Crawler = 
  { Urls : Set<string> }

[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module Crawler =

  [<CompiledName("Start")>]
  let start crawler (url:string) = 
    let { Urls = oldUrls } = crawler
    let newUrls =
      HtmlWeb().Load(url).DocumentNode.SelectNodes(".//a")
      |> Seq.cast<HtmlNode>
      |> Seq.choose (fun link ->
        match link.GetAttributeValue("href"," ") with
        | href when href.StartsWith("http://") && href.EndsWith(".html") -> Some href
        | _ -> None)
      |> Set.ofSeq
      |> Set.union oldUrls
    { crawler with Urls = newUrls }

Ваши данные и поведение теперь разделены.Crawler является неизменяемым типом записи.start принимает Crawler и возвращает новый с обновленным списком URL.Я заменил Dictionary на Set, поскольку ключи и значения одинаковы;устранены неиспользуемые let привязки, а также прокрутка в некотором сопоставлении с образцом.Это также должно иметь относительно дружественный интерфейс в C #.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...