【发布时间】:2010-05-31 02:42:10
【问题描述】:
我有一个号码 9877342931235。使用 Haskell,我需要将其显示为:
987-734293-123-5
我试过穿插列表,但当然会在每个数字之间加上“-”。我将如何做才能产生实际结果?
【问题讨论】:
-
用其他语言你会怎么做?转换为字符串,正则表达式数字组,连接 -?好吧,只需在 Haskell 中执行此操作即可。
标签: haskell pretty-print
我有一个号码 9877342931235。使用 Haskell,我需要将其显示为:
987-734293-123-5
我试过穿插列表,但当然会在每个数字之间加上“-”。我将如何做才能产生实际结果?
【问题讨论】:
标签: haskell pretty-print
这是一个简单的通用解决方案,用于将列表拆分为指定长度的部分,然后使用指定的分隔符将它们连接在一起:
splitercalate :: [Int] -> [a] -> [a] -> [a]
splitercalate (x:[]) _ s = take x s
splitercalate (x:xs) delim s =
case splitAt x s of
(a, []) -> a
(a, bs) -> a ++ delim ++ splitercalate xs delim bs
在你的情况下,splitercalate [3, 6, 3, 1] "-" $ show 9877342931235 会给你你想要的。
更新:正如Antal S-Z 在下面的评论中指出的那样,您可以使用Data.List 和Data.List.Split 中的函数更简洁地实现此功能:
splitercalate chunks sep = intercalate sep . splitPlaces chunks
您需要安装split 包(可能通过执行cabal install split 之类的操作),并导入intercalate 和splitPlaces 函数:
import Data.List (intercalate)
import Data.List.Split (splitPlaces)
这两个版本应该是等价的。如果您不介意额外的imports 和对split 包的依赖,请使用Antal S-Z——它会更好。
【讨论】:
splitercalate函数相当于splitercalate chunks sep = intercalate sep . splitPlaces chunks; intercalate 来自Data.List,splitPlaces 来自Data.List.Split。从我在 StackOverflow 上看到的答案来看,split 包确实没有得到充分利用——太糟糕了,因为这个包真的很好。
好的,如果你不想使用 Data.List.Split...
import Data.List (intercalate)
splitPlaces (n:ns) x = let (h, t) = splitAt n x 在 h : splitPlaces ns t splitPlaces_x = []
splitercalate 块 sep = 插入 sep 。 splitPlace 块
那么你的答案就是concat . splitercalate [3,5,3,1] "-" $ show 9877342931235
【讨论】: