Hello, 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.
Hello, 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)]