Haskell将char和int字符串转换为配对列表

时间:2018-03-20 15:54:21

标签: haskell

大家好我正在寻找一个功能

expand :: String -> [(Char,Int)]

带有一串字符和数字,如"a5b3c2",并将其更改为同一形式的"[('a',5),('b',3),('c',2)]"字符串的配对列表。

示例:

expand "a5b4c2"
[('a',5),('b',4),('c',2)]

expand "d9d3"
[('d',9),('d',3)]

我已经创建了一个与上述相反的功能,我想要做的就是弄清楚如何做到这一点。例如:

flatten :: [(Char, Int)] -> String
flatten [] = []
flatten ((ca,cb):cs) = ca:(show cb ++ flatten cs)

5 个答案:

答案 0 :(得分:2)

这样可以吗?

import Data.List (intersperse)
import Data.List.Split (splitPlaces, wordsBy)
mystring = "a5b2c3'

>>> map (\[x,y] -> (head x, read y :: Int)) $ splitPlaces (replicate (length mystring `div` 2) 2) $ wordsBy (==',') $ intersperse ',' mystring
[('a',5),('b',2),('c',3)]

更简单,感谢@ 4castle:

import Data.List (intersperse)
import Data.List.Split (chunksOf, wordsBy)
map (\[x,y] -> (head x, read y :: Int)) $ chunksOf 2 $ wordsBy (==',') $ intersperse ',' mystring

更简单,还要感谢@ 4castle:

import Data.List.Split (chunksOf)
map (\[x,y] -> (x, read [y] :: Int)) $ chunksOf 2 mystring

答案 1 :(得分:1)

使用像Parsec这样的解析库。学习曲线有点陡峭(我甚至不确定这是一个很好的例子),但你可以描述像这样的解析器是很少的代码。

import qualified Text.Parsec as T

parseDigit :: T.Parsec String () Int
parseDigit = fmap (read . pure) T.digit

myParser = T.many ((,) <$> T.letter <*> parseDigit)

然后

> T.parse myParser "" "a5b4c2"
Right [('a', 5),('b',4),('c',2)]

因此,您的expand可以定义为

import Data.Either
expand :: String -> [(Char, Int)]
expand s = fromRight [] (T.parse myParser "" s)

在解析器输入字符串失败的情况下返回空列表。

答案 2 :(得分:0)

如果没有任何复杂的导入,假设交替的字符和(单个)数字,您可以使用简单的递归:

f :: [(Char, Int)] -> String
f (c:d:xs) = (c,read [d]):f xs
f x        = x

答案 3 :(得分:0)

一个相对简单的解决方案:

template<typename... Args>
StrongAlias(Args&&... args) noexcept(noexcept(T(std::declval<Args>()...)))
    : value(std::forward<Args>(args)...) {}

答案 4 :(得分:0)

同样,我更喜欢列表推导和/或尾递归函数。如果函数不是折叠,则返回列表。列表推导返回列表。

let l = "a5b3c2"
[ (a,(read [b] :: Int)) | (a,b) <- zip l (tail l), elem b "1234567890"]

[( 'A',5),( 'B',3),( 'C',2)]

我发布此帖时,我不知道chunksOf函数。 chunksOf是一个非常方便的功能,我已经使用了很多。另外我想我喜欢ord函数的read函数。当你有成对时,你知道事情的所在,并且可以相应地处理。

[ (a,(ord b)-48) | (a:b:c) <- chunksOf 2 "a5b4c3"]