所以我需要从给定列表中提取元素,并使用另一个列表中给出的索引。 签名应该是这样的:
search :: [Int] -> [a] -> [a]
和结果
search [1,3,5] [34,65,67,34,23,43,54]
[65,34,43]
据我所知,这里没有标准功能,我可以用更常见的语言进行循环,但是我对haskell不太好。
答案 0 :(得分:3)
可以使用(!!) :: [a] -> Int -> Int
运算符和列表理解来实现这一目标:
search :: [Int] -> [a] -> [a]
search js xs = [xs!!j | j <- js]
但是(!!)
运算符在 O(k)中使用 k 所请求的索引,因此这将是低效的。
鉴于索引列表是有序且不超出范围,纯Haskell函数可能如下:
search :: [Int] -> [a] -> [a]
search = search' 0
where search' _ [] _ = []
search' i (j:js) xs = y : search' (j+1) js ys
where (y:ys) = drop (j-i) xs
答案 1 :(得分:3)
假设索引已排序,您可以编写自己的显式递归。
search :: [Int] -> [a] -> [a]
search indices xs = go indices 0 xs -- start from index 0
where
go :: [Int] -> Int -> [a] -> [a]
-- no more indices, we are done
go [] _ _ = []
-- more indices but no more elements -> error
go _ _ [] = error "index not found"
-- if the wanted index i is the same as the current index j,
-- return the current element y, more to the next wanted index
go (i:is) j yys@(y:_) | i==j = y : go is j yys
-- otherwise, skip y and increment the current index j
go iis j (_:ys) = go iis (j+1) ys
存在更多高级方法,但这应该是一种基本的有效替代方案。它在O(n)中运行,其中n是列表的长度。
请注意,重复调用!!
会需要O(n ^ 2)时间,因为每个!!
需要花费O(n)。
如果索引未排序,请改用go (sort indices) 0 xs
。成本增加到O(n log n)。
答案 2 :(得分:1)
您可以使用!!
operator访问列表元素,如下所示:
List!!index == value_at_that index
因此,您的功能可能如下所示:
search indexes list = [list!!x | x <- indexes]