他们是 Clojure 中从 int 到 int 作为字符的一种方式吗? 1 到?
我有一个字符串
s
,我想解析出与数字匹配的数字n
(n始终为0到9)
例如
(let [n 1]
(filter #(= ??? %) "123123123"))
哪里???将 n 作为 ,例如1 将返回“111”
或者也许有更好的方法将字符串过滤为仅单个数字的实例?
“java”方式:
user=> (Character/forDigit 1 10) ; number and radix
\1
“计算”方式(将
\0
的int添加到其中,然后返回char):
user=> (char (+ 1 (int \0)))
\1
和 Clojure 中一样,总是有一行
reduce
一行来解决最初的问题:“我只想计算该数字出现的次数。”
(reduce (fn [m ch] (update m ch (fnil inc 0))) {} "123123123")
==> {\1 3, \2 3, \3 3}
如果您是 Clojure 新手,这里有很多内容需要解开。 Reduce 用于迭代字符串,计算每个字符的出现次数并将其存储在映射中。
从内到外:
(fnil inc 0)
返回一个使用提供的任何参数运行 inc
的函数。但是,如果参数为 nil,它将替换为 0。这非常适合向地图添加新条目。
update
用于在 ch
中查找现有键 m
并计算新值(通过调用 (fnil inc 0
返回的函数)),即如果 ch
不在 m
中将运行 (inc 0) => 1
,如果 ch
位于 m
中,它将返回递增的计数器。
(fn [m ch] ...)
是归约函数。
这是最难理解的部分。它需要两个参数。
第一个是该函数的最后一个返回值(由较早的迭代生成),或者如果这是该函数第一次运行,则提供的初始值:{}
(还有第三种调用reduce的方法,请参阅(doc reduce)
)
第二个参数
ch
是提供的 String 中的当前字符(因为 String 是 CharSequence 并算作集合)。
因此,为每个字符调用归约函数,我们只需返回当前映射以及每个字符的更新计数,从
{}
开始。