ho una lista come questaHaskell Conversione Lista per lista di tuple
["peter","1000","michell","2000","kelly","3000"]
e vorrei convertire in
[("peter",1000),("michell", 2000),("kelly",3000)]
Si prega di aiuto. Grazie.
ho una lista come questaHaskell Conversione Lista per lista di tuple
["peter","1000","michell","2000","kelly","3000"]
e vorrei convertire in
[("peter",1000),("michell", 2000),("kelly",3000)]
Si prega di aiuto. Grazie.
cnv :: [String] -> [(String, Integer)]
cnv [] = []
cnv (k:v:t) = (k, read v) : cnv t
Se si desidera gestire dispari lunghezza sufficiente aggiungere cnv [x] =
variante prima ultimo
ony's solution è un po 'più breve, ma qui è una versione non ricorsiva utilizzando splitEvery
dal molto utile split
library:
cnv = map (\[name, amount] -> (name, read amount :: Int)) . splitEvery 2
I passaggi qui sono in qualche modo più chiari (almeno per me) rispetto alla versione ricorsiva.
Questo è decisamente più naturale. La libreria divisa non ha abbastanza amore. È un peccato, poiché è incredibilmente utile. –
Ora che 'splitEvery' sembra essere deprecato ora; usa invece ['chunksOf'] (https://hackage.haskell.org/package/split-0.2.2/docs/Data-List-Split.html#v:chunksOf). – sevko
Esattamente per un compito come questo trovo conveniente avere una funzione stride
di prendere ogni elemento n-esimo dalla lista:
stride _ [] = []
stride n (x:xs) = x : stride n (drop (n-1) xs)
Può essere utilizzato per convertire un elenco di coppie:
toPairs xs = zip (stride 2 xs) (stride 2 (drop 1 xs))
Un esempio (si noti che l'ultimo elemento può essere buttato via se non ha coppia):
ghci> stride 2 [1..5]
[1,3,5]
ghci> toPairs [1..7]
[(1,2),(3,4),(5,6)]
può essere ancora facilmente esteso a triplette o tuple più lunghi:
toTriplets xs = zip3 as bs cs
where as = stride 3 xs
bs = stride 3 $ drop 1 xs
cs = stride 3 $ drop 2 xs
Per eseguire la conversione da String
per intero nel tuo esempio, è possibile mappare read
funzione rispetto al secondo passo:
let lst = ["peter","1000","michell","2000","kelly","3000"] in
zip (stride 2 lst) (map read . stride 2 . drop 1 $ lst) :: [(String,Int)]
che dà:
[("peter",1000),("michell",2000),("kelly",3000)]
Puoi spiegare questa riga di codice cnv (k: v: t) = (k, leggi v): cnv t? AFAIK, il k v t è un parametro dalla lista k è la testa e v è la coda e cnv t è l'elemento successivo come k. La mia comprensione è corretta perché previosuly ho una funzione come questa. convertito :: [String] -> \t [(String, Integer)] convertito [] = [] convert (x: y: xs) = (x, y) convertire xs e perché quando aggiungo: xs non sta funzionando? Il k v t rappresenta un singolo elemento nella lista o nella lista intera? – peterwkc
Non proprio: in 'k: v: t',' k' è la testa e 'v: t' è la coda. Quindi, 'k: v: t' mette i primi due elementi della lista in' k' e 'v' e la coda rimanente in' t'. Il tuo codice ha due problemi ovvi: (a) '(x, y)' ha tipo '(String, String)', non '(String, Integer)'; e (b) non ci sono due punti prima di 'convertire xs'. (Non puoi semplicemente fare ': xs', perché hai bisogno di' [(String, Integer)] 'ma' xs' ha tipo '[String]'.) Inoltre, un suggerimento per la formattazione: linee di indent con quattro spazi vuoti per ottieni blocchi di codice (o seleziona il tuo codice e fai clic sul pulsante "101010") e frammenti di codice surround con apici inversi (\ '... codice ... \'). –
(x: xs) Ciò significa che x è la testa e l'elemento rimanente è la coda per xs. Grazie per la spiegazione. – peterwkc