我有一个像这样的列表:
["peter","1000","michell","2000","kelly","3000"]
我想将其转换为
[("peter",1000),("michell", 2000),("kelly",3000)]
请帮忙。 谢谢。
cnv :: [String] -> [(String, Integer)]
cnv [] = []
cnv (k:v:t) = (k, read v) : cnv t
如果你想处理奇数长度,只需在最后一个之前添加cnv [x] =
变体即可。
对于这样的任务,我发现拥有一个stride
函数方便从列表中获取每个第n个元素:
stride _ [] = []
stride n (x:xs) = x : stride n (drop (n-1) xs)
toPairs xs = zip (stride 2 xs) (stride 2 (drop 1 xs))
ghci> stride 2 [1..5]
[1,3,5]
ghci> toPairs [1..7]
[(1,2),(3,4),(5,6)]
它甚至可以轻松扩展到三元组或更长的元组:
toTriplets xs = zip3 as bs cs
where as = stride 3 xs
bs = stride 3 $ drop 1 xs
cs = stride 3 $ drop 2 xs
read
函数映射到第二个步幅上:let lst = ["peter","1000","michell","2000","kelly","3000"] in
zip (stride 2 lst) (map read . stride 2 . drop 1 $ lst) :: [(String,Int)]
这将会得到:
[("peter",1000),("michell",2000),("kelly",3000)]
k:v:t
中,k
是头部,而v:t
是尾部。因此,k:v:t
将列表的前两项放入k
和v
中,并将剩余的尾部放入t
中。你的代码有两个明显的问题:(a)(x,y)
的类型是(String,String)
,而不是(String,Integer)
;(b) 在convert xs
之前没有冒号。你不能只写:xs
,因为你需要[(String,Integer)]
,但是xs
的类型是[String]
。另外,一个格式化提示:使用四个空格缩进行来获得代码块(或者选择代码并点击“101010”按钮),并用反引号 (`...code...`) 包围代码片段。 - Antal Spector-Zabusky(k:v:t)
等同于(k:(v:t))
,因为在GHC.Types
中声明infixr 5:
(也就是数据[] a = [] | a:[a]
告诉你(v:t)
或[]
的含义)。 - onyinfixr 5 :
语句表示:
从右侧开始结合,优先级为5。换句话说,w:x:y:z
是w:(x:(y:z))
,而不是((w:x):y):z
。数字5
告诉你它在优先级链中的位置;例如,由于*
比+
先出现,因此*
的优先级为7,而+
的优先级为6。data [] a = [] | a : [a]
声明告诉你:
和[]
的定义,即它们构造列表的部分等等。至于格式:只需在代码前面输入“`”,然后在代码后面输入“`”。阅读编辑帮助获取更多信息。 - Antal Spector-Zabusky