【问题标题】:Is there any haskell function to concatenate list with separator?是否有任何haskell函数可以将列表与分隔符连接起来?
【发布时间】:2012-03-02 12:30:36
【问题描述】:

有没有用分隔符连接列表元素的功能? 例如:

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

感谢您的回复!

【问题讨论】:

  • 我知道 lmgtfy 的答案很糟糕,但值得注意的是,在 hoogle 上搜索“String -> [String] -> String”会得到你想要的。 haskell.org/hoogle
  • 加入空间你也有unwords
  • @sigfpe 旁注:你必须寻找[String] -> String -> String,以防其他方式返回没有答案,对吧?
  • @LayGonzález 搜索取决于排列。例如,搜索 [a] -> (a -> b) -> [b] 会返回 map 作为其第一个结果。

标签: list haskell concat


【解决方案1】:

intersperse 和 intercalate 实现的其他一些想法,如果有人感兴趣的话:

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】:

    是的,there is

    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 不确定您到底指的是什么,但是是的,这些函数都允许任意字符串作为分隔符和元素。例如,intercalate "," ["some", "", "string"] = "some,,string"intercalate "" ["foo", "bar"] = "foobar"
    • unlines 每行加一个换行符,即unlines ["A", "B"] = "A\nB\n",所以和插层不一样。
    • @KathyVanStone 有趣,我想我从未尝试过,只是假设它的工作原理类似于 unwords
    • 很高兴在标准库中有一些普通的字符串和列表操作函数,很高兴你在这里发布一个例子,因为很难找到这种日常的任何文档在 Haskell 中编程。
    【解决方案3】:

    用 foldr 写单行字并不难

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

    【讨论】:

    • 为此添加描述会很有帮助;有人将其标记为低质量。
    【解决方案4】:

    如果您想编写自己的 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)
    

    【讨论】:

    • 为什么要限制自己使用字符串?此外,您在函数应用程序周围的括号是多余的。
    • 是的,intersperse 不必是Strings,但intercalate 至少需要是Show,如果你确实使用Show ,无论如何,您都需要使用Strings 来处理它们。我仍然习惯于 Haskell 如何处理混合的中缀和前缀函数/运算符,并且我更喜欢在混合时使用括号,以防我最终想要使用 $
    • intercalate :: [a] -> [[a]] -> [a] - 为什么是Show?至于语法,Haskell 没有任何前缀运算符(- 除外,这是一个可憎的),函数应用程序比任何中缀运算符绑定得更紧密:x:s:intersperse s xs 很好(但如果你把空格:x : s : intersperse s xs(我真的不明白为什么人们喜欢忽略:周围的空格)。
    • 对。我一直忘记使用字符串只是使用列表。 Show 是因为我假设您希望结果是 String。我所说的“中缀和前缀函数/运算符”是指“前缀函数和中缀运算符”,但这并不清楚。一元 - 是死亡。至于:s 和其他中缀运算符,我是否使用空格很大程度上取决于上下文,但我总是局部一致。例如,模式匹配中的(:) 永远不会有空格,但在其他地方它取决于它是否被括号括起来以及我的心情。
    【解决方案5】:
    joinBy sep cont = drop (length sep) $ concat $ map (\w -> sep ++ w) cont
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-01-26
      • 1970-01-01
      • 2010-09-29
      • 2013-06-09
      • 2023-01-03
      • 1970-01-01
      • 1970-01-01
      • 2021-04-23
      相关资源
      最近更新 更多