获取元组列表的第一个元素

时间:2018-11-16 00:29:07

标签: list haskell tuples replicate

我有这个元组列表

[(4,'a'), (1,'b'), (2,'c'), (2,'a'), (1,'d'), (4,'e')]

我想获取每个元组的第一个元素,然后复制它以进行以下操作:“ aaaabccaadeeee”

我想到了这段代码,但是它只给了我第一个元组的副本。

replicate  (fst ( head [(4,'a'), (1,'b')])) ( snd ( head [(4,'a'), (1,'b')]))
--output is: "aaaa"

我当时正在考虑使用map来获取每个元组的副本,但是我没有成功。

3 个答案:

答案 0 :(得分:5)

由于您已经知道如何为单个元素找到正确的答案,因此您只需要进行一点递归

func :: [(Int, a)] -> [a]
func [] = []
func ((n, elem):rest) = (replicate n elem) ++ (func rest)

映射值也应该起作用。您只需要将结果字符串串联为一个即可。

func :: [(Int, a)] -> [a]
func xs = concat $ map func2 xs where 
              func2 (n, elem) = replicate n elem

或者,如果您熟悉currying

func :: [(Int, a)] -> [a]
func xs = concat $ map (uncurry replicate) xs

最后,如果您愿意使用函数组合,则定义将变为:

func :: [(Int, a)] -> [a]
func = concat . map (uncurry replicate)

使用concatmap很常见,有一个功能可以做到这一点。是concatMap

func :: [(Int, a)] -> [a]
func = concatMap (uncurry replicate)

答案 1 :(得分:1)

您对尝试使用map是正确的。但是首先让我们看看为什么您的代码不起作用

replicate  (fst ( head [(4,'a'), (1,'b')])) ( snd ( head [(4,'a'), (1,'b')]))

您要复制的第一个参数是列表的开头,即(4,'a')。然后,您在此上调用fst,因此第一个参数为4。第二个参数发生相同的事情,您得到“ a”。您看到的结果。

在使用map之前,请尝试使用递归操作。您想要获取列表的一个元素并对其应用复制,然后将其与对第二个元素应用复制的结果结合起来。

generate [] = []    
generate (x:xs) = replicate (fst x) (snd x) ++ generate xs

请注意,我正在使用模式匹配来获取列表的第一个元素。您可以使用模式匹配将元素也获取到元组中,然后就不需要使用fst / snd函数。还要注意,我正在使用模式匹配来定义空列表的基本情况。

generate [] = []
generate ((x,y):xs) = replicate x y ++ generate xs

现在要映射,因此map会将您的函数应用于列表的每个元素,这是第一次尝试

generate (x,y) = replicate x y
map generate  xs

以上结果与递归略有不同。考虑一下,map将对每个元素应用generate并将结果存储在列表中。 generate创建一个列表。因此,当您应用地图时,您将创建一个列表列表。您可以根据需要使用concat对其进行展平,这将为您提供与递归相同的结果。

最后,如果可以使用递归,那么也可以使用fold。 Fold只会对列表的每个元素应用一个函数,然后返回累积的结果(广义上来说就是这样)。

--first parameter is the function to apply, second is the accumulator, third is your list
foldr step [] xs
   where step (x,y) acc = 
                   (replicate x y) ++ acc

再次在这里,我在功能步骤中使用了模式匹配,以提取出元组的元素。

答案 2 :(得分:1)

让我们

ls = [(4,'a'), (1,'b'), (2,'c'), (2,'a'), (1,'d'), (4,'e')] 

concat [replicate i x | (i, x) <- ls]

会给予

"aaaabccaadeeee"

无积分版

concat . map (uncurry replicate)