Existe-t-il une fonction haskell pour concaténer la liste avec le séparateur?


131

Existe-t-il une fonction pour concaténer les éléments d'une liste avec un séparateur? Par exemple:

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

Merci pour toute réponse!


13
Je sais que les réponses lmgtfy sont mauvaises, mais il vaut la peine de noter qu'une recherche de "String -> [String] -> String" sur hoogle obtient exactement ce que vous voulez. haskell.org/hoogle
sigfpe

3
pour rejoindre les espaces que vous avez égalementunwords
epsilonhalbe

1
@sigfpe Commentaire secondaire: Il faudrait chercher [String] -> String -> Stringau cas où l'inverse ne renvoie pas de réponse, non?
Lay González

1
@ LayGonzález La recherche dépend des permutations. Par exemple, la recherche de [a] -> (a -> b) -> [b]retours mapcomme premier résultat.
gallais

Réponses:


228

Oui, il y a :

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

intersperse est un peu plus général:

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

De plus, pour le cas spécifique où vous souhaitez joindre un caractère espace, il y a unwords:

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

unlinesfonctionne de manière similaire, seulement que les chaînes sont implosées en utilisant le caractère de nouvelle ligne et qu'un caractère de nouvelle ligne est également ajouté à la fin. (Cela le rend utile pour la sérialisation des fichiers texte, qui doivent, selon le standard POSIX, se terminer par une nouvelle ligne à la fin)


L'un d'eux peut-il traiter d'éventuelles chaînes vides?
CMCDragonkai

3
@CMCDragonkai Je ne sais pas exactement à quoi vous faites référence, mais oui, ces fonctions autorisent toutes des chaînes arbitraires à la fois comme séparateur et comme éléments. Par exemple, intercalate "," ["some", "", "string"] = "some,,string"etintercalate "" ["foo", "bar"] = "foobar"
Niklas B.

3
unlinesajoute une nouvelle ligne à chaque ligne, c'est-à- unlines ["A", "B"] = "A\nB\n"dire que ce n'est pas la même chose qu'intercaler.
Kathy Van Stone

@KathyVanStone Intéressant, je suppose que je n'ai jamais essayé et j'ai seulement supposé que cela fonctionnait de manière analogue unwords.
Niklas B.

1
C'est bien qu'il y ait des fonctions normales de manipulation de chaînes et de listes dans la bibliothèque standard, et c'est bien que vous publiiez un exemple ici, car il est assez difficile de trouver une documentation pour ce type de programmation quotidienne dans Haskell.
Andrew Koster le

4

Il n'est pas difficile d'écrire une ligne en utilisant foldr

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

3
Il serait utile d'ajouter une description à ceci; quelqu'un l'a signalé comme étant de mauvaise qualité.
Arya McCarthy

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

3

Quelques autres idées d'implémentations d'intercalaires et d'intercalaires, si quelqu'un est intéressé:

myIntersperse :: a -> [a] -> [a]
myIntersperse _ [] = []
myIntersperse e xs = init $ xs >>= (:[e])

myIntercalate :: [a] -> [[a]] -> [a]
myIntercalate e xs = concat $ myIntersperse e xs

xs >>= féquivaut à concat (map f xs).


2

Si vous vouliez écrire vos propres versions de intercalateet 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
Pourquoi se limiter aux chaînes? En outre, vos parenthèses autour de l'application de fonction sont redondantes.
melpomene

Il est vrai interspersen'a pas besoin d' être Strings, mais intercalateaurait besoin d'être au moins Show, et si vous avez utilisé Show, vous auriez besoin d'une certaine façon de les traiter à l' aide Stringde toute façon. Je m'habitue encore à la façon dont Haskell gère les fonctions / opérateurs d'infixes et de préfixes mixtes, et je préfère le bracketing lors du mixage au cas où je $
finirais

intercalate :: [a] -> [[a]] -> [a]- pourquoi Show? En ce qui concerne la syntaxe, Haskell n'a aucun opérateur de préfixe (sauf pour -, qui est une abomination), et l'application de fonction se lie plus étroitement que n'importe quel opérateur d'infixe: x:s:intersperse s xsc'est bien (mais cela se lit beaucoup mieux si vous mettez les espaces dans: x : s : intersperse s xs(je ne Je ne comprends vraiment pas pourquoi les gens aiment laisser de côté les espaces :)).
melpomene

Droite. J'oublie toujours que travailler avec des chaînes, c'est simplement travailler avec des listes. Showétait parce que je supposais que vous voudriez que le résultat soit un String. Par «fonctions / opérateurs d'infixe et préfixe», je voulais dire «fonctions de préfixe et opérateurs d'infixe», mais ce n'était pas clair. Unaire -est la mort. En ce qui concerne les :opérateurs s et autres infixes, l'utilisation d'espaces dépend fortement du contexte, mais je suis toujours cohérent localement. par exemple, (:)dans une correspondance de motif, il n'y a jamais d'espaces, mais ailleurs, cela dépend de si elle est entre crochets et de mon humeur.
Zoey Hewll
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.