2012-02-10 22 views
86

Esiste una funzione per concatenare elementi di una lista con un separatore? Per esempio:Esiste una funzione haskell per concatenare la lista con il separatore?

> foobar " " ["is","there","such","a","function","?"] 
["is there such a function ?"] 

Grazie per qualsiasi risposta!

+11

so risposte lmgtfy sono male, ma vale la pena notare che la ricerca di "String -> [String] -> stringa" on Hoogle ottiene solo quello che vuoi. http://www.haskell.org/hoogle/ – sigfpe

+2

per unirti agli spazi hai anche 'unwords' – epsilonhalbe

+1

@sigfpe Commento a margine: dovresti cercare' [String] -> String -> String' nel caso in cui il l'altro modo non restituisce risposta, giusto? –

risposta

160

Sì, there is:

Prelude> import Data.List 
Prelude Data.List> intercalate " " ["is","there","such","a","function","?"] 
"is there such a function ?" 

intersperse è un po 'più generale:

Prelude> import Data.List 
Prelude Data.List> concat (intersperse " " ["is","there","such","a","function","?"]) 
"is there such a function ?" 

Inoltre, per il caso specifico in cui si desidera partecipare con uno spazio, non v'è unwords:

Prelude> unwords ["is","there","such","a","function","?"] 
"is there such a function ?" 

unlines opere allo stesso modo, solo che le stringhe vengono implose usando il carattere di nuova riga e che alla fine viene aggiunto anche un carattere di fine riga. (Questo lo rende utile per la serializzazione file di testo, che deve per POSIX fine serie con un carattere di fine riga)

+0

Qualcuno di questi può occuparsi di possibili stringhe vuote? – CMCDragonkai

+3

@CMCDragonkai Non sei sicuro di cosa ti riferisci esattamente, ma sì, queste funzioni consentono tutte le stringhe arbitrarie sia come separatore che come elementi. Ad esempio, 'intercalate", "[" alcuni "," "," stringa "] =" alcuni ,, stringa "' e 'intercalate" "[" foo "," bar "] =" foobar "' –

+0

'non allineate 'aggiunge una nuova riga a ogni riga, cio 'è unlines [" A "," B "] =" A \ nB \ n "', quindi non è lo stesso di intercalato. –

2
joinBy sep cont = drop (length sep) $ concat $ map (\w -> sep ++ w) cont 
0

Se si voleva scrivere le proprie versioni di intercalate e intersperse:

intercalate :: [a] -> [[a]] -> [a] 
intercalate s [] = [] 
intercalate s [x] = x 
intercalate s (x:xs) = x ++ s ++ (intercalate s xs) 

intersperse :: a -> [a] -> [a] 
intersperse s [] = [] 
intersperse s [x] = [x] 
intersperse s (x:xs) = x : s : (intersperse s xs) 
+1

Perché limitarti alle stringhe? Inoltre, i tuoi paren attorno all'applicazione funzione sono ridondanti. – melpomene

+0

Vero, 'interspersona 'non deve essere' Strings', ma 'intercalate' dovrebbe essere almeno' Show', e se _did_ usi 'Show', avrai bisogno di un modo per gestirli usando' String 's comunque. Mi sto ancora abituando a come Haskell si occupa di funzioni/operatori misti di prefissi e prefissi, e preferisco il bracketing quando si mescola nel caso in cui finisco per voler usare '$' –

+0

'intercalato :: [a] -> [[a ]] -> [a] '- perché' Mostra'? Come per la sintassi, Haskell non ha alcun operatore di prefissi (eccetto per '-', che è un abominio), e l'applicazione della funzione si lega più strettamente di qualsiasi operatore infisso:' x: s: intersperse s xs' va bene (ma legge molto meglio se metti gli spazi in: 'x: s: intersperse s xs' (non capisco davvero perché alla gente piaccia lasciare gli spazi intorno a': ')). – melpomene

1

Non è difficile scrivere uno-liner utilizzando foldr

join sep xs = foldr (\a b-> a ++ if b=="" then b else sep ++ b) "" xs 
join " " ["is","there","such","a","function","?"] 
+1

Sarebbe utile aggiungere una descrizione a questo; qualcuno lo ha contrassegnato come di bassa qualità. –

Problemi correlati