我正在寻找一个函数来替换给定索引处的字符。
例如:
replace 4 '!' "Hello World!"
-- Output: "Hell! World!"
答案 0 :(得分:2)
您可以使用replacement : strAfter
稍微改进它,并使用安全尾函数防止索引大于字符串长度时出错:
safeTail :: [a] -> [a]
safeTail [] = []
safeTail (_:xs) = xs
replaceCharAtIndex :: Int -> Char -> String -> String
replaceCharAtIndex index replacement str = strHead ++ replacement : safeTail strAfter
where (strHead, strAfter) = splitAt index str
但是应该小心:对于负索引,它将替换字符串的第一个字符。对于大于字符串长度的索引,它将追加到字符串。这两种情况本身都不是理想的行为。
我们可以通过检查负索引和空尾匹配来改变行为:
replaceCharAtIndex :: Int -> Char -> String -> String
replaceCharAtIndex index replacement str
| index < 0 = … -- index located before the string
| (_:xs) <- strAfter = strHead ++ replacement : xs
| otherwise = … -- index located after the string.
where (strHead, strAfter) = splitAt index str
因此,这里我们有两个 …
来填充这些边缘情况的结果。
答案 1 :(得分:1)
如果有人正在寻找这样的功能或类似的功能,我想出了这个:
replaceCharAtIndex :: Int -> Char -> String -> String
replaceCharAtIndex index replacement str = strHead ++ [replacement] ++ drop 1 strAfter
where (strHead, strAfter) = splitAt index str
用法:replaceCharAtIndex 4 '!' "Hello World!"
答案 2 :(得分:1)
有四种情况需要考虑:
在情况 1 中,我们返回输入不变:
replace k _ xs | null xs || k < 0 = xs
(这可以分为两个子案例
replace _ _ [] = []
replace k _ xs | k < 0 = xs
)
情况 2 通过递归隐式处理,直到我们到达情况 1。
情况 3 的处理方式是简单地返回添加到输入尾部的替换字符。
replace 0 c (x:xs) = c : xs
案例 4 是一个有趣的案例:替换列表的第 k
个元素与将列表的头部添加到替换尾部的第 k-1
个元素的结果相同。< /p>
replace k c (x:xs) = x : replace (k-1) c xs
当 k
太大时,我们最终会到达情况 1,因为 xs
会在 k
变为 0 之前变为空,从而绕过情况 3。