F# 我想过滤我的输出
F# I want to filter my output
我有一个问题,为了这个问题我已经简化了。
假设我有 2 个列表。第一个 实际上表示 类 的列表,但是 为此,假设它只是表示一个整数列表 (2,4,6,8,10)。我有另一个代表标志的整数列表,表明我是否希望 include/exclude 来自第一组的相应值。
(这不是最好的例子,但应该足以帮助我解决我真正的问题。)
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
我理想地想要 return 一个空值然后过滤掉所有空值。
非常感谢您的帮助!
List.zip set1 set2
|> List.filter (snd >> (<>) 0)
|> List.map fst
这个看起来比较简单:
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
如果您选择为您的 set2
使用 bool
的列表,它可能会更好一些:
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
这是另一个使用折叠和谓词函数来保持标志通用的版本。我在旗帜上玩得很开心 :)
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 个变体::)
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]
我有一个问题,为了这个问题我已经简化了。
假设我有 2 个列表。第一个 实际上表示 类 的列表,但是 为此,假设它只是表示一个整数列表 (2,4,6,8,10)。我有另一个代表标志的整数列表,表明我是否希望 include/exclude 来自第一组的相应值。
(这不是最好的例子,但应该足以帮助我解决我真正的问题。)
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
我理想地想要 return 一个空值然后过滤掉所有空值。
非常感谢您的帮助!
List.zip set1 set2
|> List.filter (snd >> (<>) 0)
|> List.map fst
这个看起来比较简单:
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
如果您选择为您的 set2
使用 bool
的列表,它可能会更好一些:
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
这是另一个使用折叠和谓词函数来保持标志通用的版本。我在旗帜上玩得很开心 :)
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 个变体::)
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]