简体   繁体   中英

Haskell Convert List to List of Tuples

i have a list like this

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

and i would like to convert to

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

Please help. Thanks.

cnv :: [String] -> [(String, Integer)]
cnv [] = []
cnv (k:v:t) = (k, read v) : cnv t

If you want to handle odd-length just add cnv [x] = variant before last one

ony's solution is a bit shorter, but here's a non-recursive version using splitEvery from the very handy split library :

cnv = map (\[name, amount] -> (name, read amount :: Int)) . splitEvery 2

The steps here are somewhat clearer (for me, at least) than in the recursive version.

Exactly for a task like this I find it convenient to have a stride function to take every n-th element from the list:

stride _ [] = []
stride n (x:xs) = x : stride n (drop (n-1) xs)

It can be used to convert a list to pairs:

toPairs xs = zip (stride 2 xs) (stride 2 (drop 1 xs))

An example (note that the last element may be thrown away if it doesn't have pair):

ghci> stride 2 [1..5]
[1,3,5]
ghci> toPairs [1..7]
[(1,2),(3,4),(5,6)]

It can be even easily extended to triplets or longer tuples:

toTriplets xs = zip3 as bs cs
  where as = stride 3 xs
        bs = stride 3 $ drop 1 xs
        cs = stride 3 $ drop 2 xs

To perform conversion from String to integer in your example, you can map read function over the second stride:

let lst = ["peter","1000","michell","2000","kelly","3000"] in
zip (stride 2 lst) (map read . stride 2 . drop 1 $ lst) :: [(String,Int)]

which gives:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM