0

我有两个清单。一个列表包含一些随机数据,另一个列表包含需要删除的第一个列表的索引。

例如,让我们考虑两个列表:

let a = [3,4,5,6,6,7,8]
let b = [1,3]

那么,结果输出应该是[3,5,6,7,8]。数字 4 和 6 被删除,因为它们分别位于索引位置 1 和 3。

我是 Haskell 的新手,所以很难找到解决方案。

更新:以下代码使其工作

import Data.List
dele :: Eq a => [a] -> [Int] -> [a]
dele [] _ = []
dele x [] = x
dele x (y:ys) = dele (delete (x !! y) x) ys

我只是想知道,有没有办法通过 map/fold 方式解决它?

4

3 回答 3

2
deleteByIndex :: (Enum a, Eq a, Num a) => [a] -> [b] -> [b]
deleteByIndex r = map snd . filter (\(i, _) -> notElem i r) . zip [0..]

[0..]产生一个无限列表[0, 1, 2, 3, ...]

zip使用此列表的值和表单中的输入列表构造一个对列表[(0,x), (1, y), ...]

filter需要一个函数a -> Bool。lambda 检查索引(对的第一个元素)是否在您的输入列表中r

map snd返回每对 zip 列表的第二个元素。

zip, filter,mapnotElem此处记录

于 2012-12-31T05:28:15.880 回答
2

在我的头顶上:

removeByIndex :: [Integer] -> [a] -> [a]
removeByIndex indices = map snd . filter notInIndices . zip [0..]
    where notInIndices (i,_) = i `notElem` indices
于 2012-12-31T05:44:31.223 回答
1

使用最近受到相当关注的镜头库的替代答案

import Control.Lens
>let a = [3,4,5,6,6,7,8]
>let b = [1,3]
>a^..elements (`notElem`b)
[3,5,6,7,8]

(^..) 只是 toListOf 的中缀,可用于遍历结构并从其部分中创建列表。元素功能只允许您选择要包含的元素。

其他选项是 'traverse' 来遍历可遍历对象,'both' 来遍历 (,) 并且它们与 (.) 组合在一起,因此 traverse.both 将遍历 [(1,2), (3,4)] 例如。

[(1,2), (3,4)]^..traverse.both [1,2,3,4]

于 2013-01-02T07:46:54.630 回答