当前位置:  开发笔记 > 小程序 > 正文

Haskell - 将字符串中每个单词的第一个字母大写,而不会丢失空格

如何解决《Haskell-将字符串中每个单词的第一个字母大写,而不会丢失空格》经验,为你挑选了1个好方法。

我正在做一个练习,要求我编写一个函数来大写字符串的所有首字母.

这是我到目前为止所做的:

upperFirst:: String -> String
upperFirst str =  let 
                      upperFirstForEachWord (firstLetter:others) = toUpper firstLetter : map toLower others
                  in unwords  (map upperFirstForEachWord (words str))

这就是它的工作原理:

upperFirst "" =   ""
upperFirst "hello friends!" = "Hello Friends!"

但是也:

upperFirst " " =  ""
upperFirst " a a a " = "A A A"

由于功能的原因,我在开始时,最后都会丢失白色空格words.

如何递归保存它们(不处理所有可能的情况)?

感谢您的任何帮助!



1> leftaroundab..:

words您不想像提取单词一样,而是只想拆分字符串,这样每个单词的开头也位于列表的开头.正如郝连评论说,这可以做到splitOn,但标准groupBy也会做到这一点:

import Data.List
import Data.Char

upperFirst = concat
           . map (\(c:cs) -> toUpper c : cs)
           . groupBy (\a b -> isSpace a == isSpace b)

这是如何工作的:它将所有空格或所有非空格的字符组合在一起.然后它会对每个子字符串的开头进行大写(对于空白来说也是低效的,但无害),然后将所有字符串连接在一起.

正如user3237465所说,组合mapconcat非常普遍,并且特殊情况更为常见.此外,还有一个很好的小组合器,在用一些谓词进行分组或排序时派上用场.因此你也可以这样写

import Control.Monad
import Data.Function

upperFirst = groupBy ((==)`on`isSpace) >=> \(c:cs) -> toUpper c : cs

最重要的是,你可以使用时髦的现代修改方式,对于大写部分:

import Control.Lens

upperFirst = groupBy ((==)`on`isSpace) >=> ix 0 %~ toUpper

推荐阅读
无名有名我无名_593
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有