Clojure,使用集合中不同的值替换字符的每个实例
首先,我不知道如何轻松地说出标题 我遇到的问题是在此处提供一个字符串Clojure,使用集合中不同的值替换字符的每个实例,clojure,Clojure,首先,我不知道如何轻松地说出标题 我遇到的问题是在此处提供一个字符串插入值?我希望能够用我选择的值交换?,我可以使用clojure.string/replace执行此操作 现在,我需要的用例稍微复杂一点,给定如下字符串: 这些是指定的值:?,?,?,? 我想用集合中的值替换?的值,该集合可能如下所示: [23899013] 因此,在本例中,字符串现在应为: 这些是指定的值:2389、90、13 那么?x映射到集合x(例如?0映射到集合0) ?的数量并不总是4或特定的n,但是集合的长度将始终与?的
插入值?
我希望能够用我选择的值交换?
,我可以使用clojure.string/replace
执行此操作
现在,我需要的用例稍微复杂一点,给定如下字符串:
这些是指定的值:?,?,?,?
我想用集合中的值替换?
的值,该集合可能如下所示:
[23899013]
因此,在本例中,字符串现在应为:
这些是指定的值:2389、90、13
那么?x
映射到集合x
(例如?0
映射到集合0
)
?
的数量并不总是4或特定的n,但是集合的长度将始终与?
的数量相同
我试着做了以下几点:
(mapv #(clojure.string/replace-first statement "?" %) [1 2 3 4])
但这不会在生成大小为4的向量时产生所需的结果,其中只有第一个?
被值替换
由于无法修改clojure中的变量,我迷路了,我不想让全局字符串被重新定义并传递给函数n次。您的问题可能没有涉及到其他注意事项,但如前所述,您似乎应该使用:
DaoWen已经给出了字符串的实用答案,但您必须首先将“?”替换为“%s”
但假设这不是一根绳子。Clojure有一个很棒的集合库,这通常意味着您可以避免递归或约简,但我想不出一种方法来做到这一点,而不会变得非常低效和混乱。因此,这里有一个reduce
解决方案,适用于非字符串,并带有大量注释
(let [original "these are the specified values: ?, ?, ?, ?"
replacements [2 389 90 13]
starting-accumulator [[] replacements] ; Start with an empty vector and all of the replacements.
reducing-fn (fn [[acc [r & rs :as all-r]] o] ; Apply destructuring liberally
(if (= o \?) ; If original character is "?".
[(conj acc r) rs] ; Then add the replacement character and return the rest of the remaining replacements.
[(conj acc o) all-r])) ; Else add the original character and return all the remaining replacements.
reduced (reduce reducing-fn starting-accumulator original) ; Run the reduce.
result (first reduced) ; Get the resulting seq (discard the second item: the remaining empty seq of replacements).
string-joined (apply str result)] ; The string was turned into a seq of chars by `reduce`. Turn it back into a string.
string-joined)
虽然我同意这可能是最实际的,但你问题的结尾似乎值得讨论一下,同时也是学习函数方法的问题。你基本上是在寻找一种
获取初始字符串和第一个值,并使用replace first
从中生成另一个字符串
从序列中获取该结果和下一个值,并对其使用replace first
重复2次,直到完成整个序列李>
这实际上是数学和函数编程中的一个经典模式,称为值序列的“左折”或“缩减”。函数式语言通常将其作为高阶函数构建到标准库中。在Clojure,它被称为。用它来实现您尝试的策略
(reduce #(clojure.string/replace-first %1 "?" %2)
"these are the specified values: ?, ?, ?, ?"
[2 389 90 13])
; => "these are the specified values: 2, 389, 90, 13"
请注意,与类似的函数literal不同,这需要两个参数,因此当我们进行缩减时,语句可以反弹。
如果您想查看使用reduce
时会发生什么,可以使用reduces
将其替换掉。给你
("these are the specified values: ?, ?, ?, ?" ;After 0 applications of our replace-first fn
"these are the specified values: 2, ?, ?, ?" ;;Intermediate value after 1 application
"these are the specified values: 2, 389, ?, ?" ;;after 2...
"these are the specified values: 2, 389, 90, ?"
"these are the specified values: 2, 389, 90, 13");;Final value returned by reduce
我喜欢这个!使用replace first
进行缩减是一个聪明的解决方案。
("these are the specified values: ?, ?, ?, ?" ;After 0 applications of our replace-first fn
"these are the specified values: 2, ?, ?, ?" ;;Intermediate value after 1 application
"these are the specified values: 2, 389, ?, ?" ;;after 2...
"these are the specified values: 2, 389, 90, ?"
"these are the specified values: 2, 389, 90, 13");;Final value returned by reduce