Haskell:将元组的输出列表作为字符串输出

时间:2015-09-21 01:36:13

标签: string list function haskell tuples

我试图获取这个元组列表:

[(2,"a"), (1,"a"), (1,"b"), (1,"c"), (2,"dd")]

进入此字符串输出

a 1,2

b 1

c 1

dd 2

我假设我需要使用unzip和unlines函数。但我也看到了一些使用show函数的解决方案,它使整数字符串成为可能。有什么想法吗?

3 个答案:

答案 0 :(得分:2)

如果您有此列表:

pairs = [ ("a", [1,2]), ("b", [1]), ("c", [1]), ("dd", [2]) ]

然后您可以通过以下方式获得所需的输出:

putStrLn $ unlines [ x ++ " " ++ unwords (map show ys) | (x, ys) <- pairs ]

但你必须弄清楚如何首先获得pairs列表。

答案 1 :(得分:2)

将问题分解为几个步骤。你真正想要做的是聚合在第二个位置具有相同字符串的所有元组,因此你将拥有像

这样的函数
aggregate :: [(Int, String)] -> [([Int], String)]

因此,对于输入列表,您将获得输出

[([1, 2], "a"), ([1], "b"), ([1], "c"), ([2], "dd")]

您的提示是

aggregate items = someFunc (map (\(num, str) -> ([num], str)) items)

看看foldr。在您提出有关foldr的后续问题之前,可能有数百个stackoverflow答案显示如何使用它,花一些时间来弄清楚它或它会立即关闭作为副本。

然后你需要一个函数将这个表单的单个元组转换为单个String来输出:

prettyPrint :: ([Int], String) -> String
prettyPrint (nums, str) = str ++ " " ++ joinWithComma (map show nums)

您必须自己实施joinWithComma。然后,您需要计算此数据并为汇总列表中的每个项目打印,mapM_putStrLn将是首选,因此您的main可能看起来像

main :: IO ()
main = do
    let inputList = [(2,"a"), (1,"a"), (1,"b"), (1,"c"), (2,"dd")]
    mapM_ (putStrLn . prettyPrint) (aggregate inputList)

答案 2 :(得分:0)

一步一步地工作。您可以从groupBy函数开始:

groupBy (\x y-> (snd x)==(snd y)) [(2,"a"), (1,"a"), (1,"b"), (1,"c"), (2,"dd")]

给你

[[(2,"a"),(1,"a")],[(1,"b")],[(1,"c")],[(2,"dd")]]

下一步是“累计”内部列表,mapfoldL(并且根据您的要求,sortBy}应该会有所帮助。如果你有这个,那么构造输出是微不足道的(使用show,正如你已经提到的那样。)