简体   繁体   English

在Haskell中过滤列表

[英]Filtering a list in Haskell

I am trying to start learning haskell, and a question came up. 我试图开始学习haskell,然后提出了一个问题。 Say, I have a function 说,我有一个功能

countFilter :: (a -> Bool) -> [a] -> ([a], Int)
countFilter a z = case z of []        -> ([], 0);
                            (x:xs)    -> (filter a z , length (filter a z))

It returns a list, all the items of which apply to a certain predicate and a length of that list, which is not relevant. 它返回一个列表,该列表的所有项都适用于某个谓词,并且该列表的长度无关紧要。

countFilter (<7) [1,2,4,7,11,8,2] will output ([1,2,4,2], 4) . countFilter (<7) [1,2,4,7,11,8,2]将输出([1,2,4,2], 4)

How to create such an output: ([7,11,8], 4) using the same predicate (<7)? 如何创建这样的输出: ([7,11,8], 4)使用相同的谓词(<7)?

If I understand your question correctly, you want to return all the elements that don't match the predicate (< 7) as the first element of the pair. 如果我正确理解了您的问题,则希望返回与谓词(< 7) 匹配的所有元素作为该对中的第一个元素。

In that case you can simply use the not function to flip the resulting boolean. 在这种情况下,您可以简单地使用not函数来翻转结果布尔值。
Ie create a new predicate (\\x -> not (oldPred x)) , or using function composition: (not . oldPred) : 即创建一个新的谓词(\\x -> not (oldPred x))或使用函数组合: (not . oldPred)

countFilter :: (a -> Bool) -> [a] -> ([a], Int)
countFilter f xs = (filter (not . f) xs, length (filter f xs))

Note that both filter and length can deal with empty lists, so you don't need to write a case yourself. 请注意, filterlength都可以处理空列表,因此您无需自己编写case


Alternatively, you can use the partition function to create the two lists, so that you don't filter the list twice: 另外,您可以使用分区功能来创建两个列表,这样就不必对列表进行两次过滤:

import Data.List

countFilter :: (a -> Bool) -> [a] -> ([a], Int)
countFilter f xs = let (ys, zs) = partition (not . f) xs
                   in (ys, length zs)

It's probably possible to create an even more efficient version that doesn't use length , but I leave that as an exercise :-) 可能有可能创建一个不使用length更有效的版本,但我将其留为练习:-)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM