リストとセパレータを連結するhaskell関数はありますか?


131

リストの要素をセパレータで連結する関数はありますか?例えば:

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

返信ありがとう!


13
私はlmgtfyの回答が悪いことを知っていますが、hoogleで「文字列-> [文字列]->文字列」を検索すると、期待どおりの結果が得られることに注意してください。haskell.org/hoogle
sigfpe

3
あなたも持っているスペースと結合するためunwords
イプシロンハルベ

1
@sigfpeサイドコメント:[String] -> String -> String逆に答えが返されない場合は、探す必要がありますね?
レイ・ゴンサレス

1
@LayGonzález検索は順列までです。たとえば、最初の結果として[a] -> (a -> b) -> [b]リターンmapを検索します。
ガレーヌ2016年

回答:


227

はい、あります

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

intersperse もう少し一般的です:

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

また、スペース文字で結合したい特定のケースでは、次のようになりますunwords

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

unlines文字列が改行文字を使用して内挿され、改行文字も最後に追加されることだけが同様に機能します。(これは、POSIX標準ごとに末尾の改行で終了する必要があるテキストファイルのシリアル化に役立ちます)


空の文字列を処理できますか?
CMCDragonkai 2015年

3
@CMCDragonkaiあなたが正確に何を参照しているかはわかりませんが、そうです、これらの関数はすべて、セパレータと要素の両方として任意の文字列を許可します。例えば、intercalate "," ["some", "", "string"] = "some,,string"及びintercalate "" ["foo", "bar"] = "foobar"
ニクラスB.

3
unlines各行に改行を追加します。つまりunlines ["A", "B"] = "A\nB\n"、挿入と同じではありません。
キャシーヴァンストーン

@KathyVanStone興味深いことに、私は試したことがなく、それがと同様に機能することだけを想定していましたunwords
Niklas

1
標準ライブラリにいくつかの通常の文字列とリスト操作関数があることは素晴らしいことです。また、Haskellでのこの種の日常のプログラミングに関するドキュメントを見つけるのはかなり難しいので、ここに例を投稿しているのは素晴らしいことです。
Andrew Koster

4

foldrを使用してワンライナーを書くのは難しくありません

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

3
これに説明を追加すると有益です。誰かが低品質としてフラグを立てました。
Arya McCarthy

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

3

誰かが興味を持っているなら、散在して挿入の実装の他のいくつかのアイデア:

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

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

xs >>= fと同等concat (map f xs)です。


2

intercalateおよびの独自のバージョンを作成する場合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
なぜ文字列に制限するのですか?また、関数アプリケーションの周りの括弧は冗長です。
メルポメン2017

確かにそうであるintersperse必要はありませんがStringsintercalate少なくともそうShowである必要があります。もし使用した場合ShowStringとにかくs を使用してそれらに対処する方法が必要になります。Haskellがインフィックスとプレフィックスの混合関数/演算子をどのように扱うかにまだ慣れています。使用したい場合に備えて、ミキシングの際にブラケットを使用します$
Zoey Hewll

intercalate :: [a] -> [[a]] -> [a]-なぜShow?構文に関しては、Haskellには接頭辞演算子はありません(ただし-、これはabominationです)。関数アプリケーションは、任意の内接演算子よりも強くバインドされます:x:s:intersperse s xs結構です(ただし、スペースを入れた方が読みやすくなりますx : s : intersperse s xs(人々が周りのスペースを省くのが好きな理由が本当にわかりません:))。
メルポメン

正しい。文字列を操作することは、単にリストを操作することであることを忘れてしまいます。Show結果をにしたいと思っていたからStringです。「前置関数と前置関数/演算子」とは「前置関数と前置演算子」を意味しましたが、それは不明確でした。単項-は死です。用として:sおよびその他の中置演算子、私はスペースを使用するかどうか、状況に非常に依存しますが、私は常にローカルに一貫です。たとえば、(:)パターンマッチではスペースが含まれることはありませんが、それ以外の場所では、括弧で囲まれているかどうかや、気分によって異なります。
Zoey Hewll 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.