F#我想过滤我的输出

时间:2015-06-10 20:27:34

标签: f#

我有一个问题,我为了这个问题而简化了。
我们只说我有2个清单。第一个实际上代表了一个类列表但为此目的,假设它只是代表一个int列表(2,4,6,8,10)。我有另一个表示标志的整数列表,表示我是否希望包含/排除第一组中的相应值。
(这不是最好的例子,但应该足以帮我解决我的真正问题。 )

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

我的所需输出设置为:

[2;8;10]

这是我的代码:

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

这会产生以下输出:

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

如何过滤掉这些不需要的零?
而不是| _ -> 0我理想地想要返回null然后过滤掉所有空值。

非常感谢您的帮助!

4 个答案:

答案 0 :(得分:4)

这个似乎很合理:

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

用法:

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

set1 |> filterWith set1

如果您选择为bool使用set2的列表,它可能会更好一些:

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

用法:

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

set1 |> filterWith set1

答案 1 :(得分:3)

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

答案 2 :(得分:2)

这是另一个使用fold和谓词函数来保持标志通用的版本。我对旗帜很开心:))

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]

答案 3 :(得分:1)

我将添加3个变体::)

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"

打印:

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

https://dotnetfiddle.net/UaHuTk