用 Haskell 中的字符串替换字符串中的每个数字

时间:2021-02-28 07:31:07

标签: haskell

我觉得我的愿望很前卫。

所以我有一个字符串,例如“abc1abc2abc3” 我想用给定数字的 Char 'X' 时间替换每个数字。 所以 "abc1abc2abc3" -> "abcXabcXXabcXXX"

我知道我只得到整数 <9 所以我想这样做:

myFunction givenString = let
    replaceEveryNumber '1' = 'X'
    replaceEveryNumber '8' = "XXXXXXXX"
    replaceEveryNumber c = c
    in map replaceEveryNumber myFunction

是的,由于类型不同,这实际上不起作用。

我也可以根据需要将类似的函数应用于 [String]。所以我可以从上面的代码 '1' = 'X' 改为 "1" = "X" 等等,但这里的问题是如果我有 ["abc2abc", "8"] 结果是 [" abc2abc", "XXXXXXXX"] 所以它忽略了 !!0 中字符串中的字符,我想这是有道理的,但我仍然不知道如何正确地做到这一点。

希望有人能帮帮我,谢谢!

1 个答案:

答案 0 :(得分:2)

这里有几个问题。您不是在 givenString 上映射,而是在 myFunction 上映射。由于 myFunction 是一个函数,所以它不起作用。因此,我们应该将映射表达式替换为:

myFunction givenString = let … in map replaceEveryNumber givenString

此外,replaceEveryNumber 只能返回一种类型的值,但是您的函数返回一个 Char,而其他行返回一个 String。由于您的函数应该能够返回多个 Char 的序列,因此我们应该为每一行返回一个字符串。对于 c,我们需要将其包装在一个单例列表中,以将 Char 转换为具有该字符的 String

myFunction givenString = let
    replaceEveryNumber '1' = "X"
    replaceEveryNumber '2' = "XX"
    replaceEveryNumber '3' = "XXX"
    replaceEveryNumber '4' = "XXXX"
    replaceEveryNumber '5' = "XXXXX"
    replaceEveryNumber '6' = "XXXXXX"
    replaceEveryNumber '7' = "XXXXXXX"
    replaceEveryNumber '8' = "XXXXXXXX"
    replaceEveryNumber c = [c]
    in map replaceEveryNumber givenString

现在这将生成一个 String 列表,例如:

Prelude> myFunction "abc1abc2abc3"
["a","b","c","X","a","b","c","XX","a","b","c","XXX"]

我们唯一需要做的就是连接这些字符串。我们可以使用 concat :: [[a]] -> [a],但我们也可以使用 concatMap :: (a -> [b]) -> [a] -> [b]

myFunction givenString = let
    replaceEveryNumber '1' = "X"
    replaceEveryNumber '2' = "XX"
    replaceEveryNumber '3' = "XXX"
    replaceEveryNumber '4' = "XXXX"
    replaceEveryNumber '5' = "XXXXX"
    replaceEveryNumber '6' = "XXXXXX"
    replaceEveryNumber '7' = "XXXXXXX"
    replaceEveryNumber '8' = "XXXXXXXX"
    replaceEveryNumber c = [c]
    in concatMap replaceEveryNumber givenString

最后,我们不需要为每个数字编写子句。我们可以使用 replicatedigitToInt 等函数。我把它留作练习。