clojure中的地图给出了意想不到的结果

在clojure中使用map,检查字符串是否包含大写字符。

(map #(= (clojure.string/upper-case %) %) "Hello") 

预期的结果。

(true false false false false)
(true false false false false)

不幸的是,结果出乎意料。

(false false false false false)

我做了一个实验,当我在第一个“%”中替换“H”时,结果仍然出乎意料。

(map #(= (clojure.string/upper-case "H") %) "Hello") 

(false false false false false)

当我在第二个“%”中替换“H”时,结果发生了变化,这是预期的结果。

(map #(= (clojure.string/upper-case %) "H) "Hello") 

(true false false false false)

那有什么问题?请随意发表评论。

回答

正如其他人指出的那样,将字符与字符串进行比较是行不通的。比较字符串将起作用:

(map #(= (clojure.string/upper-case %) (str %)) "Hello")
=> (true false false false false)

然而,这更直接:

(map #(Character/isUpperCase %) "Hello")
=> (true false false false false)


回答

您不能将 String 与 char 进行比较。由字符串组成的序列是一个字符列表。

(seq "Hello")
;; => (H e l l o)
(map class "Hello")
;; => (java.lang.Character java.lang.Character java.lang.Character java.lang.Character java.lang.Character)

所以在你的情况下,你的测试归结为

(= "H" H) ;; => false

这是错误的。

要使其工作,请尝试以下操作之一:

;; compare strings
(map #(= (clojure.string/upper-case %) (str %)) "Hello")
;; => (true false false false false)

;; compare chars
(map #(= (first (clojure.string/upper-case %)) %) "Hello")
;; => (true false false false false)


回答

这是因为您错误地假设map将字符串"Hello"分解为,("H" "e" "l" "l" "o")但事实并非如此!

尝试:

(map identity "Hello") ;; => (H e l l o)

因此 map 将字符串分解为字符列表而不是单个字符串的列表。

所以你(map #(= (clojure.string/upper-case %) %) "Hello")正在比较
(clojure.string/upper-case H)哪个结果"H"H. 由于一个是单个字符串,另一个是字符,结果是false- 因为类型不同。

(map #(= (clojure.string/upper-case %) (str %)) "Hello")

但是,您对原始代码的期望是什么。它返回:

功能

最有效的方法可能是使用正则表达式:

(defn has-upper-case? [s] (boolean (re-find #"[A-Z]" s)))

不太严格(不返回布尔值,而是从左到右的字符串的第一个上单字符串,或者nil如果没有找到):

(defn has-upper-case? [s] (re-find #"[A-Z]" s))

  • @madeinQuant The point of using Regex is that it makes `map` superfluous. `re-find` stops scanning as soon as it sees the first upper character in the string. No further character then is examined -> thus contributing to performance. So when using regex, you can input the entire string at once - and the scanning will end as soon as it finds first match.

以上是clojure中的地图给出了意想不到的结果的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>