首先,我不确定如何轻易说出标题。
我遇到的问题是提供一个字符串insert value here ?
我希望能够将?
替换为我选择的值,我可以使用clojure.string/replace
执行此操作。
现在,我需要的用例稍微复杂一点,给出如下字符串:
these are the specified values: ?, ?, ?, ?
我想将?
的值替换为集合中的值,如下所示:
[2 389 90 13]
所以在这个例子中,字符串现在是:
these are the specified values: 2, 389, 90, 13
所以? x
映射到collection x
(例如? 0
映射到collection 0
)
?
的数量并不总是4或特定的n,但集合的长度将始终与?
的数量相同。
我尝试了以下操作:
(mapv #(clojure.string/replace-first statement "?" %) [1 2 3 4])
但是这不能产生预期的结果,产生大小为4的vector
,其中只有第一个?
被值替换。
由于无法修改clojure中的变量,我迷失了方向,并且我不希望有一个全局字符串被重新定义并传递给函数n
次。
答案 0 :(得分:6)
虽然我同意DaoWen's answer可能是最实用的,但你的问题的结尾似乎值得讨论一下以及学习功能方法的问题。你实际上是在寻找一种方法
replace-first
从中创建另一个字符串。replace-first
。这实际上是数学和函数式编程中的经典模式,称为"左折"或者"减少"超过价值序列。函数式语言通常将其构建为标准库,作为更高阶函数。在Clojure中,它被称为reduce
。使用它实现您的尝试策略看起来像
(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"
请注意,与您的类似函数文字不同,这需要两个参数,以便在我们进行缩减时statement
可以反弹。
如果您想查看reduce
期间发生的情况,可以将其与reductions
交换。你来了
("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
答案 1 :(得分:4)
您的问题可能还有其他一些注意事项 - 但正如所写的那样,您似乎应该只使用string format
function:
(apply format
"these are the specified values: %s, %s, %s, %s"
[2 389 90 13])
; => "these are the specified values: 2, 389, 90, 13"
答案 2 :(得分:1)
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)