所以假设我有一个从2
到20
的所有整数的列表。
[2 .. 20]
我想用一个函数过滤列表(或者它是谓词?我不太习惯Haskell编程中使用的所有术语)。如果此函数的位置n等于true,我想删除位置n-1、n和1的元素。
示例:假设列表[2...20]
中位置4的元素等于6
,对于函数f
等于true。然后我想删除位置3
、4
和5
的元素,它们分别等于5
、6
和7
。所以我的最终列表如下所示:
[2,3,4,8,9,10,11,12,13,14,15,16,17,18,19,20]
我是一个没有经验的Haskell程序员,只是为了好玩。我想过使用lambda函数作为谓词,但我不太确定如何去做。我还想过使用像删除xs ys
这样的函数来删除xs
中的所有元素,这也是ys
的元素,但我也不确定如何做到这一点。
任何帮助将不胜感激!
编辑:我意识到为了产生我想要的结果而删除两个相邻的元素是错误的。此外,最好只是将受影响元素(位于位置n和n-1的元素)的值更改为0,或者以其他方式标记/标记它们,而不是完全删除它们。原因是我想一直“删除”元素,直到列表中不再有任何适合谓词的元素(及其前面的元素)。我只想从原始列表中“删除”它们。由于我的方法与原来的问题有很大的不同,我将发布一个新的问题来反映我的新方法。我想感谢你的所有回答,我从你的回答中学到了很多。非常感谢。
编辑2:这是我的新问题:当n适合谓词时,删除Haskell列表中位置n和n-1的元素
我的解决方案使用小自制列表拉链实现:
-- List zipper (think of this as a standard library routine):
data LZ a = LZ [a] a [a] deriving (Show)
listToLZ :: [a] -> LZ a
listToLZ (h:t) = LZ [] h t
lzToList :: LZ a -> [a]
lzToList (LZ l p r) = reverse l ++ p:r
moveRight, remLeft, remRight, remHere :: LZ a -> LZ a
moveRight (LZ l t (t':r)) = LZ (t:l) t' r
remLeft (LZ l p r) = LZ (tail l) p r
remRight (LZ l p r) = LZ l p (tail r)
remHere (LZ l _ (p:r)) = LZ l p r
-- And there's how one use this:
-- <business code>
traverse :: (a -> Bool) -> LZ a -> LZ a
traverse _ a@(LZ _ _ []) = a
traverse pr a@(LZ _ p _)
| pr p = traverse pr $ remHere $ remRight $ remLeft a
| True = traverse pr $ moveRight a
-- </business code>
main = let
l = [1..20]
l' = lzToList $ traverse (==4) $ listToLZ l
in
print l'
输出:
[1,2,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
这里有一种方法,但我相信还有更优雅的方法。
方法是首先将我们的列表[a]
映射到三元组[(可能a, a,可能a)]
的列表。(可能
开始发挥作用,因为第一个和最后一个元素分别缺少前身/后继。)
然后,我们可以根据我们在这个三元组类型上构造的谓词邻接ntf来实现一个过滤器。(请注意,与标准过滤器相比,您请求的过滤器是向后的——当谓词为true时,您希望删除内容。)
preprocess :: [a] -> [(Maybe a, a, Maybe a)]
preprocess xs = zip3 (beforeXs xs) xs (afterXs xs)
beforeXs :: [a] -> [Maybe a]
beforeXs xs = Nothing : (map Just xs)
afterXs :: [a] -> [Maybe a]
afterXs xs = concat [(map Just (tail xs)), [Nothing]]
middle3 :: (a, b, c) -> b
middle3 (_,x,_) = x
myfilter :: (a -> Bool) -> [a] -> [a]
myfilter f xs = map middle3 $ filter (not . adjacentF) (preprocess xs)
where
maybeF = maybe False f
adjacentF (x,y,z) = (maybeF x) || (f y) || (maybeF z)
一般来说,这应该会产生预期的结果:
*Main> myfilter (==20) [1..20]
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18]
*Main> myfilter (==1) [1..20]
[3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
*Main> myfilter (==5) [1..20]
[1,2,3,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
*Main> myfilter (\x -> x >= 12 && x <= 14) [1..20]
[1,2,3,4,5,6,7,8,9,10,16,17,18,19,20]
*Main> myfilter even [1..20]
[]
您可以在多个元素上进行模式匹配,并将过滤器应用于中间的元素。
eitherside :: (Int->Bool) -> [Int] -> [Int]
eitherside f (i1:i2:i3:is) = if (f i2)
then eitherside f is
else i1 : (eitherside f (i2:i3:is))
eitherside f is = is
*Main> eitherside (==4) [1..10]
[1,2,6,7,8,9,10]
*Main> eitherside (==5) [1..10]
[1,2,3,7,8,9,10]
*Main> eitherside (==6) [1..10]
[1,2,3,4,8,9,10]
不是这样(我原来的帖子):
eitherside :: (Int->Bool) -> [Int] -> [Int]
eitherside f (i1:i2:i3:is) = if (f i2)
then eitherside f is
else [i1,i2,i3] ++ (eitherside f is)
eitherside f is = is
*Main> eitherside (==5) [1..10]
[1,2,3,7,8,9,10]
这个糟糕的错误恰好适用于5,但由于我在“else”分支中跳过了它,所以在6中失败了。
问题内容: 我有一个清单清单: 我想从列表中删除所有不满足条件的元素。 因此,如果我想删除与之相对应的元素。 所以list_1将被修改为 我该如何选择性地做到这一点? 问题答案: 您也可以根据需要使用该条件。
问题内容: 我已经看过这篇文章: Python:通过删除每个第n个元素从现有列表构建新列表,但是由于某些原因,它对我不起作用: 我这样尝试: 此函数需要一个列表和。然后,它使用列表中的n步删除第n个元素,并打印结果。 这是我的函数调用: 错误的输出: 代替 然后我从上面的链接尝试了一个变体: 再次,函数调用: 给了我同样的错误的结果: 不是 如何正确地从列表中删除/删除/删除 第n个 项目? 问题
我有一个这样的数字列表: 如何以优雅的方式总结每个N(让我们假设2)个元素并将列表转换为: 编辑:我想出了以下解决方案: 它是有效的,但我仍然在寻找一个更易读、更简单的方法。
我有一个包含和以及的字符串。 我们如何删除和,同时保持机智?
所以我有超过1000000列 但我只需要前10000列,基本上将列从n(int)降至n(int)。谢谢!
本文向大家介绍在C ++中找到(1 ^ n + 2 ^ n + 3 ^ n + 4 ^ n)mod 5,包括了在C ++中找到(1 ^ n + 2 ^ n + 3 ^ n + 4 ^ n)mod 5的使用技巧和注意事项,需要的朋友参考一下 在本教程中,我们将解决以下问题。 给定一个整数n,我们必须找到(1 n +2 n +3 n +4 n)%5 如果n大,则数字(1 n +2 n +3 n +4