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

List 获取元组列表的第一个元素,list,haskell,tuples,replicate,List,Haskell,Tuples,Replicate,我有这个元组列表 [(4,'a'), (1,'b'), (2,'c'), (2,'a'), (1,'d'), (4,'e')] 我想得到每个元组的第一个元素,然后复制它来生成以下内容:aaaabccaadeee 我提出了这段代码,但它只提供了第一个元组的复制 replicate (fst ( head [(4,'a'), (1,'b')])) ( snd ( head [(4,'a'), (1,'b')])) --output is: "aaaa" 我曾想用map for获得每个元组的复制

我有这个元组列表

[(4,'a'), (1,'b'), (2,'c'), (2,'a'), (1,'d'), (4,'e')]
我想得到每个元组的第一个元素,然后复制它来生成以下内容:aaaabccaadeee

我提出了这段代码,但它只提供了第一个元组的复制

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

我曾想用map for获得每个元组的复制,但没有成功。

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

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
或者,如果您熟悉:

最后,如果您习惯于使用函数组合,则定义为:

func :: [(Int, a)] -> [a]
func = concat . map (uncurry replicate)
使用concat和map非常常见,有一个函数可以做到这一点。这是concatMap


因为您已经知道如何为单个元素找到正确答案,所以只需要一点递归

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
或者,如果您熟悉:

最后,如果您习惯于使用函数组合,则定义为:

func :: [(Int, a)] -> [a]
func = concat . map (uncurry replicate)
使用concat和map非常常见,有一个函数可以做到这一点。这是concatMap


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

replicate  (fst ( head [(4,'a'), (1,'b')])) ( snd ( head [(4,'a'), (1,'b')]))
要复制的第一个参数是列表的开头,即4“a”。然后您在此调用fst,因此第一个参数是4。第二个参数也会发生同样的情况,得到“a”。你看到的结果

在使用map之前,让我们尝试使用递归来实现这一点。您需要获取列表中的一个元素,并对其应用replicate,然后将其与对第二个元素应用replicate的结果相结合

generate [] = []    
generate (x:xs) = replicate (fst x) (snd x) ++ generate xs
请注意,我正在使用模式匹配来获取列表的第一个元素。您也可以使用模式匹配来获取元组中的元素,这样就不需要使用fst/snd函数。还要注意,我使用模式匹配来定义空列表的基本情况

generate [] = []
generate ((x,y):xs) = replicate x y ++ generate xs
现在来看map,map将把你的函数应用到列表中的每个元素,这里是第一次尝试

generate (x,y) = replicate x y
map generate  xs
上述结果将与递归略有不同。想想看,map将对每个元素应用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

在这里,我在函数步骤中再次使用了模式匹配来提取元组的元素。

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

replicate  (fst ( head [(4,'a'), (1,'b')])) ( snd ( head [(4,'a'), (1,'b')]))
要复制的第一个参数是列表的开头,即4“a”。然后您在此调用fst,因此第一个参数是4。第二个参数也会发生同样的情况,得到“a”。你看到的结果

在使用map之前,让我们尝试使用递归来实现这一点。您需要获取列表中的一个元素,并对其应用replicate,然后将其与对第二个元素应用replicate的结果相结合

generate [] = []    
generate (x:xs) = replicate (fst x) (snd x) ++ generate xs
请注意,我正在使用模式匹配来获取列表的第一个元素。您也可以使用模式匹配来获取元组中的元素,这样就不需要使用fst/snd函数。还要注意,我使用模式匹配来定义空列表的基本情况

generate [] = []
generate ((x,y):xs) = replicate x y ++ generate xs
现在来看map,map将把你的函数应用到列表中的每个元素,这里是第一次尝试

generate (x,y) = replicate x y
map generate  xs
上述结果将与递归略有不同。想想看,map将对每个元素应用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
在这里,我在函数步骤中再次使用了模式匹配来提取元组的元素。

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

无点版本

concat . map (uncurry replicate) 

无点版本

concat . map (uncurry replicate) 

通常情况下,不使用fst和snd更为明显,而且绝对不使用head或!!而是使用模式匹配来获取元素。对于列表元素的处理,不管是元组还是其他什么,列表理解在语法上都非常好。f=>>=uncurry replicate是一种非常好的方法。你的列表是ils in[s | n,c map返回相同大小的数组。所以在本例中,它会给你字符串数组。要在一个操作中完成它,你需要
需要折叠功能,它会给出累积的结果。通常情况下,不使用fst和snd以及肯定不使用head或!!而是使用模式匹配来获取元素。对于列表元素的处理,无论是元组还是其他什么,列表理解在语法上都非常好。f=>>=uncurry replicate是一种很好的方法。您的列表是ils[s | n,c map返回相同大小的数组。因此,在本例中,它将为您提供字符串数组。要在一次操作中完成此操作,您需要fold函数,该函数将给出累积结果。