【问题标题】:Clojure Enlive: How to simplify this extract fn from scrape3.cljClojure Enlive:如何简化从 scrape3.clj 提取的 fn
【发布时间】:2013-03-01 12:17:27
【问题描述】:

我遵循了 enlive 教程,必须说我对 Enlive 解析网络的能力印象深刻。现在,我来进一步查看此处可用的 scrape3.clj:https://github.com/swannodette/enlive-tutorial/blob/master/src/tutorial/scrape3.clj

Swannodette 在设计这个例子方面做得很好,但我觉得我们可以让它变得更枯燥一些。

我的问题:我会重写这个提取函数以使其更干燥:

(defn extract [node]
  (let [headline (first (html/select [node] *headline-selector*))
        byline   (first (html/select [node] *byline-selector*))
        summary  (first (html/select [node] *summary-selector*))
        result   (map html/text [headline byline summary])]
    (zipmap [:headline :byline :summary] (map #(re-gsub #"\n" "" %) result)))) 

如果您对程序的其他元素有其他想法,请随时分享!

编辑: 我玩了一圈,想出了:

    (defn extract [node]
      (let [s [*headline-selector* *byline-selector* *summary-selector*] 
            selected (map #(html/text (first (html/select [node] %))) s)
            cleaned  (map #(re-gsub #"\n" "" %) selected)]
        (zipmap [:headline :byline :summary] cleaned)))

【问题讨论】:

    标签: clojure enlive


    【解决方案1】:

    first (html/select [node] 可以提升到本地函数:

    (defn extract [node]
      (let [selector (fn [sel]) (html/select [node] sel)
            headline (selector *headline-selector*)
            byline   (selector *byline-selector*)
            summary  (selector *summary-selector*)
            result   (map html/text [headline byline summary])]
        (zipmap [:headline :byline :summary] (map #(re-gsub #"\n" "" %) result))))
    

    然后可以删除中间名称,尽管这些有助于使代码的重点清晰,因此这是个人喜好问题:

    (defn extract [node]
      (let [selector (fn [selector]) (html/select [node] selector)
            result   (map html/text 
                       (map selector [*headline-selector* 
                                      *byline-selector* 
                                      *summary-selector*]))]
        (zipmap [:headline :byline :summary] (map #(re-gsub #"\n" "" %) result)))) 
    

    【讨论】:

    • blush 我想我已经不在 Emacs 壁橱里了 ;-)
    【解决方案2】:

    为了使函数的结果“更明显”,我将使用映射文字,如下所示:

    (defn extract [node]
      (let [sel #(html/text (first (html/select [node] %)))
            rem #(re-gsub #"\n" "" %)
            get-text #(-> % sel rem)]
        {:headline (get-text *headline-selector*)
         :byline (get-text *byline-selector*)
         :summary (get-text *summary-selector*)
         }))
    

    【讨论】:

    • 非常有趣的解决方案。就一个问题。为什么%1 而不是%?其他问题,你能写:get-text (comp rem sel)?
    • % 也可以,更新了答案。我通常更喜欢 -> 宏,因为您可以从第一个表达式开始到最后一个表达式来了解它在做什么,而 comp 在其他方向工作,即最后一个在前,然后是前一个等等。
    猜你喜欢
    • 2012-03-08
    • 1970-01-01
    • 2014-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-01
    相关资源
    最近更新 更多