Есть ли функция для объединения элементов списка с разделителем? Например:
> foobar " " ["is","there","such","a","function","?"]
["is there such a function ?"]
Спасибо за любой ответ!
Есть ли функция для объединения элементов списка с разделителем? Например:
> foobar " " ["is","there","such","a","function","?"]
["is there such a function ?"]
Спасибо за любой ответ!
Да, есть:
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 ?"
Кроме того, для конкретного случая, когда вы хотите присоединиться с пробелом, существует _ 4_:
Prelude> unwords ["is","there","such","a","function","?"]
"is there such a function ?"
unlines
работает аналогично, только что строки складываются с использованием символа новой строки и что символ новой строки также добавляется в конец. (Это делает его полезным для сериализации текстовых файлов, которые в соответствии со стандартом POSIX должны заканчиваться новой строкой в конце)
intercalate "," ["some", "", "string"] = "some,,string"
и intercalate "" ["foo", "bar"] = "foobar"
- person Niklas B.; 23.06.2015
unlines
добавляет новую строку к каждой строке, то есть unlines ["A", "B"] = "A\nB\n"
, поэтому это не то же самое, что и вставка.
- person Kathy Van Stone; 27.04.2017
unwords
.
- person Niklas B.; 27.04.2017
Нетрудно написать однострочник с помощью foldr
join sep xs = foldr (\a b-> a ++ if b=="" then b else sep ++ b) "" xs
join " " ["is","there","such","a","function","?"]
Еще несколько идей реализации вкраплений и вставок, если кому-то интересно:
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)
.
Если вы хотите написать свои собственные версии 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)
intersperse
не обязательно должно быть Strings
, но intercalate
должно быть по крайней мере Show
, и если вы действительно использовали Show
, вам все равно понадобится какой-то способ справиться с ними, используя String
s. Я все еще привыкаю к тому, как Haskell имеет дело со смешанными инфиксными и префиксными функциями / операторами, и я предпочитаю использовать скобки при микшировании на случай, если я захочу использовать $
- person Zoey Hewll; 04.02.2017
intercalate :: [a] -> [[a]] -> [a]
- почему Show
? Что касается синтаксиса, то в Haskell нет никаких префиксных операторов (кроме -
, что является мерзостью), а приложение-функция связывает сильнее, чем любой инфиксный оператор: x:s:intersperse s xs
это нормально (но он читается намного лучше, если вы вставите пробелы в: x : s : intersperse s xs
(Я действительно не понимаю, почему людям нравится оставлять пробелы вокруг :
)).
- person melpomene; 04.02.2017
Show
было потому, что я предполагал, что вы хотите, чтобы результат был String
. Под инфиксными и префиксными функциями / операторами я имел в виду префиксные функции и инфиксные операторы, но это было неясно. Унарный -
- это смерть. Что касается :
s и других инфиксных операторов, то, использую ли я пробелы, сильно зависит от контекста, но я всегда локально согласован. например, (:)
в сопоставлении с шаблоном никогда не имеет пробелов, но в другом месте это зависит от того, заключено ли оно в квадратные скобки, и от моего настроения.
- person Zoey Hewll; 04.02.2017
unwords
- person epsilonhalbe   schedule 10.02.2012[String] -> String -> String
в случае, если другой способ не вернет ответа, верно? - person Lay González   schedule 09.03.2014map
в качестве первого результата. - person gallais   schedule 19.06.2016