Reputation: 371
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
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
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
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