Có bất kỳ chức năng haskell để nối danh sách với dấu phân cách không?


131

Có một chức năng để nối các phần tử của một danh sách với một dấu phân cách không? Ví dụ:

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

Cảm ơn cho bất kỳ trả lời!


13
Tôi biết câu trả lời của lmgtfy rất tệ, nhưng đáng chú ý là việc tìm kiếm "Chuỗi -> [Chuỗi] -> Chuỗi" trên hoogle có được những gì bạn muốn. haskell.org/hoogle
sigfpe

3
để tham gia với các không gian bạn cũng cóunwords
epsilonhalbe

1
@sigfpe Nhận xét bên: Bạn sẽ phải tìm [String] -> String -> Stringtrong trường hợp cách khác trả về không có câu trả lời, phải không?
Lay González

1
@ LayGonzález Việc tìm kiếm tùy thuộc vào hoán vị. Ví dụ, tìm kiếm [a] -> (a -> b) -> [b]lợi nhuận maplà kết quả đầu tiên của nó.
gallais

Câu trả lời:


227

Vâng, :

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

intersperse nói chung hơn một chút:

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

Ngoài ra, đối với trường hợp cụ thể mà bạn muốn tham gia với một nhân vật không gian, có unwords:

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

unlineshoạt động tương tự, chỉ có các chuỗi được mã hóa bằng cách sử dụng ký tự dòng mới và một ký tự dòng mới cũng được thêm vào cuối. (Điều này làm cho nó hữu ích cho việc tuần tự hóa các tệp văn bản, phải theo tiêu chuẩn POSIX kết thúc bằng một dòng mới


Bất kỳ của nó có thể đối phó với các chuỗi trống có thể?
CMCDragonkai

3
@CMCDragonkai Không chắc chắn chính xác những gì bạn đang đề cập đến, nhưng vâng, tất cả các hàm này đều cho phép các chuỗi tùy ý vừa là dấu phân cách vừa là phần tử. Ví dụ: intercalate "," ["some", "", "string"] = "some,,string"intercalate "" ["foo", "bar"] = "foobar"
Niklas B.

3
unlinesthêm một dòng mới vào mỗi dòng, nghĩa là unlines ["A", "B"] = "A\nB\n"nó không giống như xen kẽ.
Kathy Van Stone

@KathyVanStone Thú vị, tôi đoán tôi chưa bao giờ thử và chỉ cho rằng nó hoạt động tương tự unwords.
Niklas B.

1
Thật tuyệt khi có một số hàm thao tác danh sách và chuỗi bình thường trong thư viện chuẩn và thật tuyệt khi bạn đăng một ví dụ ở đây, vì thật khó để tìm thấy bất kỳ tài liệu nào cho loại lập trình hàng ngày này trong Haskell.
Andrew Koster

4

Không khó để viết một lớp lót bằng cách sử dụng Foldr

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

3
Nó sẽ có ích để thêm một mô tả cho điều này; ai đó đã đánh dấu nó là chất lượng thấp.
Arya McCarthy

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

3

Một số ý tưởng khác về việc triển khai xen kẽ và xen kẽ, nếu ai đó quan tâm:

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

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

xs >>= ftương đương với concat (map f xs).


2

Nếu bạn muốn viết phiên bản của riêng mình intercalateintersperse:

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
Tại sao lại giới hạn bản thân trong chuỗi? Ngoài ra, parens của bạn xung quanh ứng dụng chức năng là dư thừa.
melpomene

Đúng, interspersekhông cần Strings, nhưng intercalateít nhất cũng cần phải như vậy Show, và nếu bạn đã sử dụng Show, bạn sẽ cần một số cách để đối phó với chúng bằng cách sử dụng Strings. Tôi vẫn quen với cách Haskell xử lý các hàm / toán tử tiền tố hỗn hợp và tiền tố hỗn hợp và tôi thích đặt dấu ngoặc khi trộn trong trường hợp cuối cùng tôi muốn sử dụng$
Zoey Hewll 4/2/2017

intercalate :: [a] -> [[a]] -> [a]- tại sao Show? Về cú pháp, Haskell không có bất kỳ toán tử tiền tố nào (ngoại trừ -, đó là một sự gớm ghiếc) và ứng dụng hàm liên kết chặt chẽ hơn bất kỳ toán tử infix nào: x:s:intersperse s xsvẫn ổn (nhưng nó đọc tốt hơn nhiều nếu bạn đặt khoảng trắng vào: x : s : intersperse s xs(Tôi không 't thực sự hiểu lý do tại sao mọi người thích để lại không gian xung quanh :)).
melpomene

Đúng. Tôi tiếp tục quên rằng làm việc với các chuỗi chỉ làm việc với các danh sách. Showlà bởi vì tôi đã cho rằng bạn muốn kết quả là a String. Theo "các hàm / toán tử tiền tố và toán tử" Tôi có nghĩa là "các hàm tiền tố và toán tử infix", nhưng điều đó không rõ ràng. Unary -là cái chết. Đối với :các toán tử infix và khác, việc tôi sử dụng khoảng trắng phụ thuộc nhiều vào ngữ cảnh, nhưng tôi luôn nhất quán cục bộ. ví dụ, (:)trong một trận đấu mẫu không bao giờ có khoảng trắng, nhưng ở nơi khác, nó phụ thuộc vào việc nó được đặt trong ngoặc và theo tâm trạng của tôi.
Zoey Hewll
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.