【问题标题】:Using let inside ->> macro使用 let inside ->> 宏
【发布时间】:2014-08-02 16:36:05
【问题描述】:

我已经开始学习clojure了。我被困在 ->> 宏中使用 let

代码是:

 (defn make-summary [wordStr]
                                        ;// split string into words
  (let [words (clojure.string/split wordStr #"[\[\]\(\),.\s+]") 
                                        ;// convert words to lowercase.
        lowerCaseWords (map clojure.string/lower-case words)]
                                        ;// remove stop words
    (->> (remove-stop-words lowerCaseWords)           
                                        ;// count the frequency of words  
        ;// ---------- HERE IS THE PROBLEM ------------------------------ 
        (let [totalWords (count )]  ;// <--- HOW TO MAKE MACRO PUT THE THING HERE ???
          (count-frequency)
                                        ;// sort on the basis of frequency
          (sort #(> (get %1 1) (get %2 1)))
                                        ;// find the keywords

        )
        )))

我被困在 defn 函数中的第二个let

我该如何编码?

【问题讨论】:

  • 你不能那样做。 ->> 将参数作为表单的最后一项插入。它不会进入表单并在任意位置插入内容。为什么你仍然需要第二个 let,你会在哪里使用 totalWords?
  • 顺便说一句,您可能想使用frequencies
  • 如果你真的想使用 let in a ->> 或者需要在不同位置的参数,那么你可以使用 as->
  • @kima 你能解释更多吗..这就是我要找的

标签: clojure


【解决方案1】:

您可以将原始代码与 clojure 1.5 中添加的 as-> 线程宏一起使用 它允许您指定位置,而不是将其参数插入到每个表单的第一个 (->) 或最后一个 (->>) 位置:

(as-> [1 2 3] x
     (conj x 4)
     (map inc x)) ;=> '(2 3 4 5)

我认为,建议是尽可能使用 -> 或 ->> 并且只有在不容易做到时才回退到 as->。 @Thumbnail 的汇总函数是使用 ->> 获得的可读性的一个很好的例子。

您可以将 as-> 视为以下代码的便捷简写:

(let [x [1 2 3]
      x (conj x 4)
      x (map inc x)] x)

这是你用 as-> 编写的代码的相关部分:

(as-> (remove-stop-words lowerCaseWords) x
      (let [totalWords (count x)] .....

【讨论】:

    【解决方案2】:

    遵循@DiegoBasch 的建议...

    如果你正在寻找

    • 按使用频率降序排列的单词
    • 消除停用词和
    • 利用-&gt;&gt;

    那么以下可能适合:

    (defn summarise [text stop-words]
      (->> text
           (re-seq #"[a-zA-Z]+")
           (map clojure.string/lower-case)
           (remove stop-words)
           frequencies
           (sort-by (comp - val))
           (map key)))
    

    举例

    (summarise "Mary had a HUGE a lamb" #{})
    ("a" "mary" "had" "huge" "lamb")
    
    (summarise "Mary had a HUGE a lamb" #{"huge"})
    ("a" "mary" "had" "lamb")
    

    注意事项

    • 该函数将单词检测为字母序列而不是 检测特定的分隔符。您可以撤消此更改 如果您愿意。
    • 我倾向于确保停用词也是小写的: 使用(set (map clojure.string/lower-case stop-words)) 而不是 stop-wordsremove。否则大写的停用词 信件将无效。

    【讨论】:

    • 感谢您的努力,但它没有回答我的问题。你说了很多好话..但问题在于使用 let inside ->> .. 上下文无关紧要。
    【解决方案3】:

    不可能让-&gt;&gt; 在表单最后一项以外的任何位置插入参数。但这可以用于实现它的技巧:

    (defn make-summary [wordStr]
                                            ;// split string into words
    
      (let [words (clojure.string/split wordStr #"[\[\]\(\),.\s+]") 
                                            ;// convert words to lowercase.
            lowerCaseWords (map clojure.string/lower-case words)]
                                            ;// remove stop words
        (->> (remove-stop-words lowerCaseWords)           
                                            ;// count the frequency of words  
    
        (fn [LCW] (let [totalWords (count LCW)]  ;// <--- HOW TO MAKE MACRO PUT THE THING HERE ???
              (count-frequency)
                                            ;// sort on the basis of frequency
              (sort #(> (get %1 1) (get %2 1)))
                                            ;// find the keywords
    
            )
            ))))
    

    我所做的是将东西包裹在函数中,现在您可以将参数放在任何地方。

    【讨论】:

      猜你喜欢
      • 2015-05-08
      • 2017-10-14
      • 1970-01-01
      • 2018-04-29
      • 2018-11-21
      • 2013-07-16
      • 1970-01-01
      • 2013-02-13
      • 2021-01-01
      相关资源
      最近更新 更多