¿Existe una función para concatenar elementos de una lista con un separador? Por ejemplo:
> foobar " " ["is","there","such","a","function","?"]
["is there such a function ?"]
Gracias por cualquier respuesta!
Sí, hay :
Prelude> import Data.List
Prelude Data.List> intercalate " " ["is","there","such","a","function","?"]
"is there such a function ?"
intersperse
es un poco más general:
Prelude> import Data.List
Prelude Data.List> concat (intersperse " " ["is","there","such","a","function","?"])
"is there such a function ?"
Además, para el caso específico en el que desea unirse con un carácter de espacio, hay unwords
:
Prelude> unwords ["is","there","such","a","function","?"]
"is there such a function ?"
unlines
funciona de manera similar, solo que las cadenas están implosionadas usando el carácter de nueva línea y que también se agrega un carácter de nueva línea al final. (Esto lo hace útil para serializar archivos de texto, que deben cumplir con el estándar POSIX con una nueva línea final)
intercalate "," ["some", "", "string"] = "some,,string"
yintercalate "" ["foo", "bar"] = "foobar"
unlines
agrega una nueva línea a cada línea, es decir unlines ["A", "B"] = "A\nB\n"
, no es lo mismo que intercalar.
unwords
.
No es difícil escribir una línea usando foldr
join sep xs = foldr (\a b-> a ++ if b=="" then b else sep ++ b) "" xs
join " " ["is","there","such","a","function","?"]
joinBy sep cont = drop (length sep) $ concat $ map (\w -> sep ++ w) cont
Algunas otras ideas de implementaciones de intercalar e intercalar, si alguien está interesado:
myIntersperse :: a -> [a] -> [a]
myIntersperse _ [] = []
myIntersperse e xs = init $ xs >>= (:[e])
myIntercalate :: [a] -> [[a]] -> [a]
myIntercalate e xs = concat $ myIntersperse e xs
xs >>= f
es equivalente a concat (map f xs)
.
Si desea escribir sus propias versiones de intercalate
y 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)
intersperse
no tiene que ser Strings
, pero intercalate
tendría que ser por lo menos Show
, y si se hizo uso Show
, que había necesidad de una cierta manera de tratar con ellos usando String
s de todos modos. Todavía me estoy acostumbrando a cómo Haskell se ocupa de las funciones / operadores mixtos de infijo y prefijo, y prefiero poner entre paréntesis cuando mezclo en caso de que termine con ganas de usarlo$
intercalate :: [a] -> [[a]] -> [a]
- por que Show
? En cuanto a la sintaxis, Haskell no tiene ningún operador de prefijo (excepto -
, que es una abominación), y la aplicación de función se ajusta más que cualquier operador de infijo: x:s:intersperse s xs
está bien (pero se lee mucho mejor si pone los espacios en: x : s : intersperse s xs
(No Realmente no entiendo por qué a la gente le gusta dejar los espacios a su alrededor :
)).
Show
fue porque estaba asumiendo que querrías que el resultado fuera a String
. Por "funciones / operadores de infijo y prefijo" quise decir "funciones de prefijo y operadores de infijo", pero eso no estaba claro. Unario -
es la muerte. En cuanto a los :
operadores infix y otros, si uso espacios depende en gran medida del contexto, pero siempre soy localmente coherente. por ejemplo, (:)
en una coincidencia de patrones nunca tiene espacios, pero en otros lugares depende de si está entre corchetes y de mi estado de ánimo.
unwords
[String] -> String -> String
en caso de que la otra forma no devuelva respuesta, ¿verdad?[a] -> (a -> b) -> [b]
retornosmap
como primer resultado.