Haskell如何从两个int列表中返回一个int列表



如果CCD_ 1,和list2 = [14,14,24,24,1,1,2,2]如何返回一个[0,0,1,1,2,2,3,3]的int列表

我使用了功能

elemIndex' :: Eq a => a -> [a] -> Int
elemIndex' x = fromMaybe (-1) . elemIndex x

以及第一个的结果0从列表1中获取单个数字的索引但我想要的是

findIndex :: [Int] -> [Int] -> [Int] 

这将输入两个int列表,并返回基于键列表的索引值如何递归地获取一个列表的索引,或者使用任何导入函数(如map)。

您在分解问题方面做得很好。您已经认识到,您正在为第二个列表中的每个元素做同样的事情,并且您已经编写了一个函数来捕捉这种行为。

elemIndex' :: Eq a => a -> [a] -> Int
elemIndex' x = fromMaybe (-1) . elemIndex x

现在,您需要使用此函数并将其应用于另一个列表的每个元素,将结果收集到一个新列表中。也就是说,你想要一个看起来像的东西

mystery :: (a -> b) -> [a] -> [b]

我们可以搜索Hoogle并找到确切的函数:map

map :: (a -> b) -> [a] -> [b]

map采用一个函数和一个列表,并将其应用于每个元素。您有一个函数(elemIndex',带有适当的部分应用程序),还有一个列表(示例中为list2)。所以让我们把它放在一起。

findAll :: Eq a => [a] -> [a] -> [Int]
findAll haystack needles = map (x -> elemIndex' x haystack) needles

Haskell中有很多流式函数,比如map,了解/弄清楚在特定情况下使用哪一个是需要实践的。如果你有疑问,请记住,你可以使用Hoogle来搜索一个类型,也可以简单地递归地做任何你想做的事情(如果你不知道list1 = [14,24,1,2,11,7,23,8,12,22,20,0,15,19,4,9,10,21,18,17,3,13,16,5,6,25]0的存在,你可以用一点递归自己写),随着时间的推移,你会掌握它的窍门。祝你在哈斯克尔的努力中好运!

作为@SilvioMayolo的答案的替代方案,您可以使用Map数据结构。我们在list1中每个值的索引中zip,然后将其转换为映射,然后只查找list2中的每个值。

import Data.Map
import Data.List
list1 = [14,24,1,2,11,7,23,8,12,22,20,0,15,19,4,9,10,21,18,17,3,13,16,5,6,25]
list2 = [14,14,24,24,1,1,2,2]
map1 = Data.Map.fromList $ list1 `zip` [0..]
-- fromList [(0,11),(1,2),(2,3),(3,20),(4,14),(5,23),(6,24),
--           (7,5),(8,7),(9,15),(10,16),(11,4),(12,8),(13,21),
--           (14,0),(15,12),(16,22),(17,19),(18,18),(19,13),
--           (20,10),(21,17),(22,9),(23,6),(24,1),(25,25)]
list3 = Data.List.map (map1 !) list2
-- [0,0,1,1,2,2,3,3]

最新更新