在Clojure函数中移动参数

时间:2012-04-28 10:37:13

标签: clojure

我正在处理4clojure问题29:"Get the Caps"

(= (__ "HeLlO, WoRlD!") "HLOWRD")

我在REPL中写了一个解决方案:

user=> (apply str (filter (fn [foo] (some #(= % foo) 
         (map char (range 65 91)))) "AbC"))
"AC"

但正如你可以看到我的参数“AbC”嵌套在两个括号中。我如何将我的参数移到外面以便我可以在4clojure测试中使用它?我是否以错误的方式解决了这个问题?

3 个答案:

答案 0 :(得分:5)

您不需要将a参数移动到外部,您可以使用与创建过滤功能相同的技术,即使用fn

(fn [string] 
  (apply str 
    (filter 
      (fn [foo] (some #(= % foo) (map char (range 65 91)))) 
      string)))

作为一个例子,以下两个陈述是相同的:

(+ 1 2 3)
((fn [n] (+ 1 2 n)) 3)

但是,要真正回答您的问题,您可以使用comp(“撰写”)和partial将参数移至允许eta conversion(这是最后一个的技术名称)你试图做的部分操作):

(comp (partial apply str)
      (partial filter (fn [foo] (some #(= % foo) 
                                       (map char (range 65 91))))))

此表达式现在是一个函数,它接受一个字符串,过滤大写字母,然后将其转换回字符串(comp从右到左应用函数的通知)。

(注意,最后一个表达可能不是非常惯用的Clojure;第一种方法,或者其他人的建议之一,更好。)

答案 1 :(得分:3)

您应该将函数作为解决方案传递。类似的东西:

(fn [text] 
    (apply str (filter (fn [foo] (some #(= % foo) 
                                        (map char (range 65 91)))) 
                       text)))

您还可以使用Character.isUpperCase过滤所有大写字母:(filter (fn [ch] (Character/isUpperCase ch) text)

答案 2 :(得分:2)

我不熟悉4Clojure,但如果允许,你可以使用clojure.string/replace

以下应该可以解决问题:

(fn [s] (clojure.string/replace s #"[^A-Z]" ""))

不在A到Z范围内的所有内容都将替换为空字符串。