F # I want to filter my output

I have a problem which I simplified for this question.
Let's say I have 2 lists. The first is actually a list of classes, but for that, let's say it just represents a list of ints (2,4,6,8,10). I have another ints list that represents flags, indicating if I want to include / exclude the corresponding values ​​from the first set.
(This is not the best example, but should be sufficient to help me solve my real problem.)

let set1 = [2;4;6;8;10]
let set2 = [1;0;0;1;1]

      

My desired output :

[2;8;10]

      

This is my code:

let solution = 
    List.map2 (fun a b -> 
        match b with
        | 1 -> a 
        | _ -> 0
    ) set1 set2

      

this outputs the following output:

val solution : int list = [2; 0; 0; 8; 10]

      

How can I filter out these unwanted zeros?
Instead, | _ -> 0

I ideally want to return zero and then filter out all zeros.

Your help will be much appreciated!

+3


source to share


4 answers


This seems reasonable:

let filterWith set2 set1 =
    List.zip set1 set2 
    |> List.filter (fun (_,x) -> x=1) 
    |> List.map fst

      

using:

let set1 = [2;4;6;8;10]
let set2 = [1;0;0;1;1]

set1 |> filterWith set1

      




if you decide to use the list bool

for your own set2

, it might get a little nicer:

let filterWith set2 set1 =
    List.zip set1 set2 
    |> List.filter snd
    |> List.map fst

      

using:

let set1 = [2;4;6;8;10]
let set2 = [true;false;false;true;true]

set1 |> filterWith set1

      

+4


source


List.zip set1 set2
|> List.filter (snd >> (<>) 0)
|> List.map fst

      



+3


source


Here's another version using the fold function and a predicate to maintain a common flag. I had fun with flags :)

let filterByFlag pred l flags =
  List.zip l flags
  |> List.fold (fun s (x,flag) -> if pred(flag) then x::s else s) []
  |> List.rev

let l = [2;4;6;8;10]
let flags = ["πŸ‘";"πŸ‘Ž";"πŸ‘Ž";"πŸ‘";"πŸ‘"]

filterByFlag (fun t -> t = "πŸ‘") l flags
>val it : int list = [2; 8; 10]

      

+2


source


I'll add 3 options: :)

let set1 = [2;4;6;8;10]
let set2 = [1;0;0;1;1]

let filterWith2 (set1:int list) (set2:int list) = 
    [0..set1.Length-1]
    |> List.choose (fun i ->
        match set2.[i] with
        | 1 -> Some set1.[i]
        | _ -> None)

let filterWith3 (set1:int list) (set2:int list) = 
      List.foldBack2(fun x y acc -> if y=1 then x::acc else acc) set1 set2 [] 

open System.Linq
let filterWith4 (set1:int list) (set2:int list) = 
      set1.Where(fun _ i -> set2.[i]=1) |> List.ofSeq

filterWith2 set1 set2 |> printfn "%A"
filterWith3 set1 set2 |> printfn "%A"
filterWith4 set1 set2 |> printfn "%A"

      

Printing

[2; 8; 10]
[2; 8; 10]
[2; 8; 10]

      

https://dotnetfiddle.net/UaHuTk

+2


source







All Articles