2010-06-18 10 views
7

목록에 목록을 변환 난이하스켈은 튜플

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

같은 목록을 가지고 있고 내가 도와주세요

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

로 변환하고 싶습니다. 감사합니다. . 당신은 단지 마지막

답변

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

조금 짧은,하지만 여기에 매우 편리 split library에서 splitEvery를 사용하여 비 재귀 버전의 :

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

여기 단계는 재귀 버전보다 다소 명확합니다 (최소한 나를 위해).

+1

이 코드 줄을 설명 할 수 있습니까? AFAIK, k v t는 목록 k의 매개 변수이고 머리는 v이고 꼬리는 다음 요소 k입니다. previosuly 내가 이런 기능을 가지고 있기 때문에 내 이해가 정확합니다. 변환 :: [문자열] -> \t [(문자열, 정수)] 변환 [] = [] 변환 (X : Y : XS) = (X, Y)는 XS 변환 및 왜 추가 때 xs 작동하지 않습니다? k가 목록 또는 전체 목록의 단일 요소를 나타 냅니까? – peterwkc

+3

'k : v : t'에서'k'가 머리이고'v : t'가 꼬리입니다. 따라서'k : v : t'는 목록의 처음 두 항목을'k'와'v'에 넣고 나머지 꼬리는't'에 넣습니다. 코드에는 두 가지 명백한 문제가 있습니다. (a)'(x, y)'는 (String, Integer)가 아닌'(String, String) '유형을가집니다. (b)'convert xs '앞에 콜론이 없습니다. (': (String, Integer) '는 필요하지만'xs'는'[String]'타입을 가지고 있기 때문에': xs'를 할 수 없습니다.) 또한 형식 팁 : 4 개의 공백이있는 들여 쓰기 라인 코드 블록을 가져 오거나 (코드를 선택하고 "101010"버튼을 클릭하십시오) 백틱 (\'... 코드 ... \')으로 코드 스 니펫을 둘러싸십시오. –

+0

(x : xs) 즉, x는 머리이고 나머지 요소는 xs의 꼬리입니다. 설명해 주셔서 감사합니다. – peterwkc

8

ony's solution 전에 cnv [x] = 변형을 추가 홀수 길이를 처리하려면

+2

이것은 확실히 자연 스럽습니다. 분할 된 라이브러리는 충분한 사랑을 얻지 못합니다. 엄청나게 유용하기 때문에 너무 나쁩니다. –

+0

이제'splitEvery'는 더 이상 사용되지 않는 것으로 보입니다. ['chunksOf'] (https://hackage.haskell.org/package/split-0.2.2/docs/Data-List-Split.html#v:chunksOf)를 대신 사용하십시오. – sevko

3

내가 찾을이 같은 작업을 편리 목록에서 매 n 번째 요소를 가지고 가기 위하여 stride 기능이 정확히 위해 :

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)] 
,369

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 기능을 매핑 할 수 있습니다 : 1,363,210

그것은 심지어 쉽게 세 쌍둥이 이상 튜플로 확장 할 수

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