I'm trying to find a way to do the following function with foldl:
count a = length (filter (\i -> i) a)
It just counts the number of values that are true in a list of booleans. I did try it myself with
count = foldl (\i ->
case i of
True -> (1+)
False -> (0+)
) 0
Which did not even compile. Any suggestions?
After this introduction, let's continue with how you can count TRUE or FALSE values in Excel. COUNTIFS and COUNTIF functions are used to count values based on a criteria. Both function share a similar syntax, which involves range and criteria pairs.
df = pd.DataFrame ( {'A': [True, False, True, False, True]}) print (df ['A'].value_counts ()) # True 3 # False 2 # Name: A, dtype: int64 To calculate True or False values separately, don't compare against True / False explicitly, just sum and take the reverse Boolean via ~ to count False values:
Will get you the total amount of True values per column. For row-wise count, set axis=1 . Adding a sum () in the end will get you the total amount in the entire DataFrame. returns a boolean value. True indicates a missing value. returns column wise sum of True values. returns total no of NA elements.
To calculate True or False values separately, don't compare against True / False explicitly, just sum and take the reverse Boolean via ~ to count False values: This works because bool is a subclass of int, and the behaviour also holds true for Pandas series / NumPy arrays.
So let's check out the types of the functions involved
Prelude> :t (\i -> case i of { True -> (1+) ; False -> (0+) })
(\i -> case i of { True -> (1+) ; False -> (0+) }) :: (Num t) => Bool -> t -> t
Prelude> :t foldl
foldl :: (a -> b -> a) -> a -> [b] -> a
So for your list of Bool
s, b is Bool, but the function you're using has Bool
as the first argument, not the second. The accumulated value is the first argument. So instead you could do
foldl (\acc p -> case p of { True -> acc + 1 ; False -> acc }) 0
Or if you'd just like to fix the argument order, use your original function with flip
Prelude> :t flip
flip :: (a -> b -> c) -> b -> a -> c
foldl (flip (\i -> case i of
True -> (1+)
False -> (0+)
)) 0
Or you can be more succinct: foldl (flip ((+) . fromEnum)) 0
How about:
count = foldl (\i v -> if v then i + 1 else i) 0
Another way to do it without foldl
:
count list = sum $ map fromEnum list
Credit to Logan for pointing out fromEnum
. Hadn't heard of that one before.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With