[英]group a list of lists and count occurence of the second element for a unique first element
[英]Delete Second Occurence of Element in List - Haskell
我正在尝试编写一个删除列表中第二次出现的元素的函数。 目前,我编写了一个删除第一个元素的函数:
removeFirst _ [] = []
removeFirst a (x:xs) | a == x = xs
| otherwise = x : removeFirst a xs
作为一个起点。 但是,我不确定这个功能是否可以通过列表理解来完成。 有没有办法使用地图实现这个?
编辑:现在我添加了一个removeSecond函数调用第一个
deleteSecond :: Eq a => a -> [a] -> [a]
deleteSecond _ [] = []
deleteSecond a (x:xs) | x==a = removeFirst a xs
| otherwise = x:removeSecond a xs
但是现在返回的列表将删除元素的第一次和第二次出现。
好吧,假设你有removeFirst
- 如何搜索第一次出现,然后在剩余列表中使用removeFirst
?
removeSecond :: Eq a => a -> [a] -> [a]
removeSecond _ [] = []
removeSecond a (x:xs) | x==a = x:removeFirst a xs
| otherwise = x:removeSecond a xs
您也可以将其作为折叠实现。
removeNth :: Eq a => Int -> a -> [a] -> [a]
removeNth n a = concatMap snd . scanl go (0,[])
where go (m,_) b | a /= b = (m, [b])
| n /= m = (m+1, [b])
| otherwise = (m+1, [])
并在行动:
λ removeNth 0 1 [1,2,3,1]
[2,3,1]
λ removeNth 1 1 [1,2,3,1]
[1,2,3]
我使用scanl
而不是foldl
或foldr
所以它可以从左到右传递状态并在无限列表上工作:
λ take 11 . removeNth 3 'a' $ cycle "abc"
"abcabcabcbc"
这是使用List
提供的函数的本能实现:
import List (elemIndices);
removeSecond x xs = case elemIndices x xs of
(_:i:_) -> (take i xs) ++ (drop (i+1) xs)
_ -> xs
removeNth n x xs = let indies = elemIndices x xs
in if length indies < n
then xs
else let idx = indies !! (n-1)
in (take idx xs) ++ (drop (idx+1) xs)
注意:这个不能处理无限列表,并且它的性能可能不适合非常大的列表。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.