【问题标题】:Do some replacement in Haskell List Comprehensions在 Haskell List Comprehensions 中做一些替换
【发布时间】:2013-02-25 10:55:57
【问题描述】:

我的问题是,如果我输入一个包含 Hello, today is a Nice Day!! 之类的字符串,我怎样才能去掉空格和标点符号,并将大写字母替换为小写字母?

我知道如何删除它们,但不知道如何替换它们。

还要去掉标点符号。

对不起,我不知道如何处理字符串,只有数字。

testList xs = [if x = [,|.|?|!] then " "  | x<-xs] 

【问题讨论】:

    标签: string list haskell list-comprehension


    【解决方案1】:

    要去掉标点符号,您可以使用像这样的过滤器

    [x | x<-[1..10], x `mod` 2 == 0]
    

    您使用的“如果”不会过滤。将 if 放在列表推导的“地图”部分只会在两个选项之间进行选择,但您无法将它们过滤掉。

    至于将事物转换为小写,它与您已经可以在数字中实现的技巧相同:

    [x*2 | x <- [1..10]]
    

    【讨论】:

    • 那么会不会是 [x|xmod 2 == 0]?
    • @BobBobington 不,您使用更容易阅读的mod x 2x ``mod`` 2。和1 + 2(+) 1 2几乎一样
    • @BobBobington:你是对的。这就是我在 Python 中编码过多所得到的:P
    • @kyticka:在问题中你可以使用缩进。在评论中,您可以使用反斜杠转义反引号:`\`` -> `
    【解决方案2】:

    我已经很久没有在 Haskell 中编写代码了,但是下面应该删除无效字符(用空格替换它们)并将字符从大写转换为小写:

    import Data.Char
    
    replace invalid xs = [if elem x invalid then ' ' else toLower x | x <- xs]
    

    另一种方法:

    repl invalid [] = []
    repl invalid (x:xs) | elem x invalid = ' ' : repl invalid xs
                        | otherwise      = toLower x : repl invalid xs
    

    您可以像这样调用replace(或repl)函数:

    replace ",.?!" "Hello, today is a Nice Day!!"
    

    上面的代码会返回:

    "hello  today is a nice day  "
    

    编辑:我在 Haskell 中使用来自 Data.ChartoLower 函数,但如果你想自己编写,请在 Stack Overflow 上查看。以前有人问过这个问题。

    【讨论】:

      【解决方案3】:

      这是一个没有导入模块的版本,使用 fromEnum 和 toEnum 来选择允许哪些字符:

      testList xs = 
        filter (\x -> elem (fromEnum x) ([97..122] ++ [32] ++ [48..57])) $ map toLower' xs 
          where toLower' x = if elem (fromEnum x) [65..90] 
                                then toEnum (fromEnum x + 32)::Char 
                                else x
      
      OUTPUT:
      *Main> testList "Hello, today is a Nice Day!!"
      "hello today is a nice day"
      

      对于无模块替换功能,这样的事情可能会起作用:

      myReplace toReplace xs = map myReplace' xs where
        myReplace' x
          | elem (fromEnum x) [65..90] = toEnum (fromEnum x + 32)::Char
          | elem x toReplace           = ' '
          | otherwise                  = x
      
      OUTPUT:
      *Main> myReplace "!," "Hello, today is a Nice Day!! 123"
      "hello  today is a nice day   123"
      

      【讨论】:

      • 记住 OP 也想用空格替换一些字符。
      【解决方案4】:

      你会在Data.Char找到你需要的功能:

      import Data.Char
      
      process str = [toLower c | c <- str , isAlpha c]
      

      虽然个人认为函数组合的方式比较清晰:

      process = map toLower . filter isAlpha
      

      【讨论】:

      • 这并不能解决问题——OP希望用空格替换无效字符,而不是删除它们。请参阅@OscarMederos 的回答。
      • “我怎样才能去掉空格和标点符号,并用小写字母替换大写字母?”在我看来,这听起来像是 OP 想要删除空格。
      • 如果他的意思是别的意思,也许 OP 可以编辑问题以便清楚起见。
      【解决方案5】:
      import Data.Char
      

      如果要将标点符号转换为空格并将字符从大写转换为小写:

      testList xs = [if x `elem` ",.?!" then ' ' else toLower x | x<-xs]
      

      例如:testList "TeST,LiST!" == "test list "

      如果要删除标点符号并将字符从大写转换为小写:

      testList2 xs = [toLower x | x<-xs, not (x `elem` ",.?!")]
      

      示例:testList2 "Te..S,!t LiS?T" == "test list"

      如果不想或者不能导入Data.Char,这是toLower的一个实现:

      toLower' :: Char -> Char
      toLower' char 
          | isNotUppercase = char -- no change required
          | otherwise = toEnum (codeChar + diffLowerUpperChar) -- char lowered
          where
            codeChar = fromEnum char -- each character has a numeric code
            code_A = 65
            code_Z = 90
            code_a = 97
            isNotUppercase = codeChar < code_A || codeChar > code_Z
            diffLowerUpperChar = code_a - code_A
      

      【讨论】:

      • 这应该是我回答中的评论。你已经看过了吗?
      • 这很有帮助。谢谢你。教授给我们的 power point 只有数字的例子,但这解决了我很多关于操作字母的问题。
      • 但是我将如何实现 toLower?它给了我不在范围内,我尝试添加导入 data.char,但这也给了我一个错误。编辑:我让它工作 nvm。
      【解决方案6】:

      使用应用样式

      《Learn You a Haskell for Great Good!》一书中的一段文字引述:

      在列表中使用 applicative 样式通常可以很好地替代 列出理解。在第二章中,我们希望看到所有 [2,5,10] 和 [8,10,11] 的可能产品,所以我们这样做了:

      [ x*y | x <- [2,5,10], y <- [8,10,11]]         
      

      我们只是从两个列表中提取并在它们之间应用一个函数 元素的每一种组合。这可以在应用程序中完成 风格也是:

      (*) <$> [2,5,10] <*> [8,10,11]
      

      这对我来说似乎更清楚,因为更容易看出我们只是 在两个非确定性计算之间调用 *。如果我们想要所有 这两个列表中超过 50 个的可能产品,我们只是 做:

      filter (>50) $ (*) <$> [2,5,10] <*> [8,10,11]
      -- [55,80,100,110]
      

      Functors, Applicative Functors and Monoids

      【讨论】:

        猜你喜欢
        • 2016-07-08
        • 1970-01-01
        • 1970-01-01
        • 2016-08-04
        • 1970-01-01
        • 2012-04-21
        • 2019-04-21
        • 2011-01-26
        • 1970-01-01
        相关资源
        最近更新 更多