Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Can an F# query expression filter for items that are NOT in a sub-query?

I have the following sample that finds the numbers in s1 that are not in s2.

let s1 = seq { 1..3 }
let s2 = seq { 3..4 }

s1
|> Seq.filter (fun x -> s2 |> Seq.forall (fun y -> x <> y))
|> Seq.iter (fun x -> printfn $"{x}")

This prints 1 and 2 as expected.

Can this also be expressed as a query expression?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

First of all, I think your existing solution using filter and forall is perfectly fine and does not need to be converted to query expressions – those are great for SQL-like queries and querying databases, but I think they are often a bit unhelpful for basic sequence processing.

To answer your question, you can do this using a nested query (as in the answer from Violet), but using the all operation:

query { 
  for x in s1 do
  where (query { for y in s2 do all (y > 0) })
  select x }

This is really exactly the same as your original code – the outer query implements filter and the nested query implements forall. You could also freely combine the two:

query { 
  for x in s1 do
  where (Seq.forall (fun y -> x <> y) s2)
  select x }

Although I guess it gets a bit nicer if you turn s2 into a set first:

let s2set = set s2 

query { 
  for x in s1 do
  where (not (s2set.Contains x))
  select x }
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading