Clojure / ClojureScript中的不区分大小写过滤器

7

I have this function :

(defn list-data [alist filter-text]
 (filter (fn [x] (if (nil? filter-text) true
                     (> (.indexOf x filter-text) -1))) alist))

(list-data ["Lion" "Zebra" "Buffalo" "Antelope"] "a")
;=> ("Zebra" "Buffalo")

有没有更加惯用的方式来编写这个函数并且不区分大小写,也就是说我希望 (list-data ["Lion" "Zebra" "Buffalo" "Antelope"] "a") 返回以下内容:

;=> ("Zebra" "Buffalo" "Antelope")

感谢您!(这需要在.cljs文件中运行)

@缩略图 谢谢!你找得真不错! - leontalbot
1
另一种解决这个问题的方法是保留小写值的缓存,然后使用普通的 clojure.string/starts-with?,这可能更快但会使用更多内存。 - Petrus Theron
2个回答

20

在Clojure中,你通常会使用正则表达式来实现这个功能。在Java中的正则表达式中,你可以通过在所需匹配的地方加入不区分大小写的标志,或在正则表达式开头添加全局不区分大小写的标志来实现。

  (filter #(re-find #"(?i)a" %)
          ["Lion" "Zebra" "Buffalo" "Antelope"])

纯Javascript正则表达式仅支持全局标志。它们作为字符串给出,并作为正则表达式构造函数的第二个参数:

  (filter #(re-find (js/RegExp. "a" "i") %)
          ["Lion" "Zebra" "Buffalo" "Antelope"])

然而,为了方便起见并使Java和Javascript之间的正则表达式保持相似,Clojurescript读取器将全局Java样式标志(即在正则表达式开头的标志)转换为它们对应的Javascript全局标志。

因此,第一个示例在Clojurescript中也可以工作。请注意,非全局标志在Clojure中有效,但在Clojurescript中无效。


Javascript正则表达式不支持内联修饰标志(例如,(?i))。 - amalloy
据我所读,Clojurescript阅读器支持Java类型内联标志。 - NielsK
1
我明白了。https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/compiler.clj#L192-L196会获取正则表达式开头的任何内联标志,并将其用于全局标志。因此,您实际上无法在内联中更改内容(因为JavaScript不支持它),但是如果您想要全局标志,可以使用类似Clojure的语法。 - amalloy
这个cljs om示例可以很好地工作。https://dev59.com/9X7aa4cB1Zd3GeqPwORt 谢谢! - leontalbot
@amalloy 扩展了答案,现在我用的是普通键盘。 - NielsK
不受时间限制的ClojureScript预处理片段的URL,@amalloy提供了链接:https://github.com/clojure/clojurescript/blob/4bbbd60/src/clj/cljs/compiler.clj#L192-L196 - chbrown

4
(defn list-data [alist filter-text]
 (if-let [filter-text (some-> filter-text not-empty .toLowerCase)]
   (filter #(-> % 
                .toLowerCase 
                (.indexOf filter-text)
                (not= -1)) 
           alist)
   alist))

谢谢!这个例子也可以正常工作:https://dev59.com/9X7aa4cB1Zd3GeqPwORt 你的回答比@Nielsk的回答稍微冗长一些。 - leontalbot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接