我有一个像这样的列表
["peter","1000","michell","2000","kelly","3000"]
我想转换为
[("peter",1000),("michell", 2000),("kelly",3000)]
请帮忙。 谢谢。
答案 0 :(得分:14)
cnv :: [String] -> [(String, Integer)]
cnv [] = []
cnv (k:v:t) = (k, read v) : cnv t
如果你想处理奇数长度,只需在最后一个
之前添加cnv [x] =
变体
答案 1 :(得分:8)
ony's solution有点短,但这是一个非递归版本,使用splitEvery
中非常方便的cnv = map (\[name, amount] -> (name, read amount :: Int)) . splitEvery 2
:
{{1}}
这里的步骤(对我来说至少比)在递归版本中更清晰。
答案 2 :(得分:3)
正是对于这样的任务,我发现使用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
要在示例中执行从String
到整数的转换,您可以在第二步中映射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)]