Haskell转换列表到元组列表

时间:2010-06-18 03:33:32

标签: list haskell tuples

我有一个像这样的列表

["peter","1000","michell","2000","kelly","3000"]

我想转换为

[("peter",1000),("michell", 2000),("kelly",3000)]

请帮忙。 谢谢。

3 个答案:

答案 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)]