Listeyi ayırıcıyla birleştirmek için herhangi bir haskell işlevi var mı?


132

Bir listenin öğelerini ayırıcıyla birleştirmek için bir işlev var mı? Örneğin:

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

Herhangi bir cevap için teşekkürler!


13
Lmgtfy yanıtlarının kötü olduğunu biliyorum, ancak hoogle'da "String -> [String] -> String" aramasının tam da istediğinizi aldığını belirtmek gerekir. haskell.org/hoogle
sigfpe

3
sahip olduğunuz alanlara katılmak içinunwords
epsilonhalbe

1
@sigfpe Side yorumu: [String] -> String -> StringDiğer yolun cevap vermemesi durumunda aramanız gerekir , değil mi?
Lay González

1
@ LayGonzález Arama permütasyonlara bağlıdır. Örneğin , ilk sonuç olarak [a] -> (a -> b) -> [b]iadeleri aramak map.
gallais

Yanıtlar:


228

Evet, var :

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

intersperse biraz daha geneldir:

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

Ayrıca, bir boşluk karakteriyle birleştirmek istediğiniz özel durum için unwords:

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

unlinesbenzer şekilde çalışır, yalnızca dizeler satırsonu karakteri kullanılarak içe doğru yerleştirilir ve sonuna bir satırsonu karakteri de eklenir. (Bu, metin dosyalarını serileştirmek için kullanışlı hale getirir; bu, her POSIX standardının sonunda bir satırsonu ile bitmesi gerekir)


Bunlardan herhangi biri olası boş dizelerle başa çıkabilir mi?
CMCDragonkai

3
@CMCDragonkai Tam olarak neyi kastettiğinizden emin değilim, ama evet, bu işlevlerin tümü hem ayırıcı hem de öğeler olarak rastgele dizelere izin verir. Örneğin, intercalate "," ["some", "", "string"] = "some,,string"veintercalate "" ["foo", "bar"] = "foobar"
Niklas B.

3
unlinesher satıra bir satırsonu ekler unlines ["A", "B"] = "A\nB\n", yani interkalate ile aynı değildir.
Kathy Van Stone

@KathyVanStone İlginç, sanırım hiç denemedim ve sadece benzer şekilde çalıştığını varsaydım unwords.
Niklas B.

1
Standart kitaplıkta bazı normal dizgi ve liste işleme işlevleri olması güzel ve burada bir örnek göndermeniz güzel, çünkü Haskell'de bu tür günlük programlama için herhangi bir belge bulmak oldukça zor.
Andrew Koster

4

Foldr kullanarak tek satırlık yazmak zor değil

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

3
Buna bir açıklama eklemek faydalı olacaktır; birisi bunu düşük kaliteli olarak işaretledi.
Arya McCarthy

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

3

Birisi ilgilenirse, serpiştirme ve iç içe geçme uygulamalarının bazı diğer fikirleri:

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

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

xs >>= feşdeğerdir concat (map f xs).


2

Kendi intercalateve intersperse: sürümlerinizi yazmak istiyorsanız :

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
Neden kendinizi dizelerle sınırlayasınız? Ayrıca, işlev uygulamasının etrafındaki parensleriniz fazladır.
melpomene

Doğru, interspersegerek olmayabilir Strings, ama intercalateen azından olması gerekir Showve eğer yaptığımız kullanımını Show, kullanmakta onlarla başa çıkmak için bir yol gerekiyordu Stringler zaten. Haskell'in karma ek ve önek işlevleri / operatörleri ile nasıl başa çıktığına hala alışmaya başladım ve kullanmak istemem durumunda karıştırırken parantez oluşturmayı tercih ediyorum$
Zoey Hewll

intercalate :: [a] -> [[a]] -> [a]- neden Show? Sözdizimine gelince, Haskell'in herhangi bir önek operatörü yoktur ( -iğrenç olan hariç ) ve fonksiyon uygulaması herhangi bir infix operatöründen daha sıkı bağlanır: x:s:intersperse s xsiyi (ancak boşlukları koyarsanız çok daha iyi okur: x : s : intersperse s xs(Ben yok İnsanların neden etrafta boşluk bırakmayı sevdiklerini gerçekten anlamıyorum :)).
melpomene

Sağ. Dizelerle çalışmanın sadece listelerle çalışmak olduğunu unutup duruyorum. Showçünkü sonucun a olmasını isteyeceğinizi varsayıyordum String. "Ek ve önek işlevleri / işleçleri" derken "önek işlevleri ve ek işleçleri" ni kastettim, ancak bu açık değildi. Unary -ölümdür. :S ve diğer infix operatörlerine gelince , boşluk kullanıp kullanmama büyük ölçüde bağlama bağlıdır, ancak her zaman yerel olarak tutarlıyım. örneğin, (:)bir kalıp eşleşmesinde hiçbir zaman boşluk yoktur, ancak başka yerlerde parantez içinde olup olmadığına ve ruh halime bağlıdır.
Zoey Hewll
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.