riad
riad

Reputation: 371

Filtering a List Haskell

I just started learning Haskell about filtering lists. Suppose I have the following list : [2, 3, 4, 5, 8, 10, 11] I would like to keep only those numbers in the list, which are not divisible by the other members.

The result of our example would be : [2, 3, 5, 11]

Upvotes: 2

Views: 10936

Answers (3)

josejuan
josejuan

Reputation: 9566

Using filter

filter :: (a -> Bool) -> [a] -> [a]

and from Data.Numbers.Primes the function

isPrime :: Integral int => int -> Bool

may be

filter isPrime [2, 3, 4, 5, 8, 10, 11]

or using list comprehension

[ x | x <- [2, 3, 4, 5, 8, 10, 11], isPrime x]

change filter predicate as you wish, e.g.

-- None `xs` element (different than `x`) divide `x`
noneDiv xs x = and [x `mod` y /= 0 | y <- xs, x /= y]

now

myFilter xs = filter (noneDiv xs) xs

or

myFilter xs = [x | x <- xs, noneDiv xs x]

Upvotes: 2

Mark Karpov
Mark Karpov

Reputation: 7599

On GHC,

Prelude> :m + Data.List
Prelude Data.List> nubBy (\a b -> rem a b == 0) [2,3,4,5,8,10,11]
[2,3,5,11]

does the trick. On Haskell98-compatible systems (e.g. Hugs), use nubBy (\b a -> rem a b == 0).

This answer was posted as a comment by Will Ness.

Upvotes: 3

MasterMastic
MasterMastic

Reputation: 21286

[x | x <- src, all (\y -> x `rem` y /= 0) (filter (<x) src)]
where src = [2,3,4,5,8,10,11]

It should be noted that you actually also mean dividable by other numbers that are below it, and not just any number in that list, which is why there's a filter in the 2nd argument for all.

The result, of course, is the one you expect in your question: [2,3,5,11].


Here's how it works (and if I'm missing anything, let me know and I'll update).

I'll explain the code side-by-side with normal English. I suggest you just read just the English first, and afterwards see how each statement is expressed in code - I think it should be the most friendly for a newcomer.
Also note that I flipped the arguments for filter and all below (it is invalid!) to make the explanation fluid.

[x|: Construct a list made out of x
x <- src: Where x is an element from src
,: But only the elements that satisfy the following predicate/rule:
all of the numbers from
(filter src (<x)): src that are lesser-than the current x
(\y -> x 'rem' y /= 0): must not yield a remainder equal to 0.
]

For the code part to make sense, make sure you've familiarized yourself with all, filter, rem, and the syntax for: list comprehensions, lambda expressions, sections, and backticks.

Upvotes: 5

Related Questions