f#array.filter基于bool数组

时间:2011-05-17 20:47:41

标签: f#

如果我有数组A,并且我有另一个具有相同长度isChosen的bool数组A,我如何从A isChosen建立一个新数组true 1}}是A.[isChosen]?像Array.filter之类的东西?我无法直接使用isChosen,因为A不是Array.filteri元素的函数,而Array.mapi没有{{1}}。

4 个答案:

答案 0 :(得分:7)

zip应该有帮助:

let l = [|1;2;3|]
let f = [|true; false; true|]

let r = [| for (v, f) in Seq.zip l f do if f then yield v|]
// or
let r = (l, f) ||> Seq.zip |> Seq.filter snd |> Seq.map fst |> Seq.toArray 

答案 1 :(得分:3)

尝试使用zip操作符

seq.zip A isChosen 
|> Seq.filter snd
|> Seq.map fst
|> Array.ofSeq

这将创建一系列元组,其中一个值来自A,另一个来自isChosen。这会将值组合在一起,并且可以很容易地在Seq.filter表达式中过滤掉它们

答案 2 :(得分:2)

它不像其他答案那样优雅或“功能”,但每隔一段时间我就会想要一个温和的提示,你可以在F#中使用循环和数组索引:

let A = [|1;2;3|]
let isChosen = [|true; false; true|]
let r = [| for i in 0..A.Length-1 do 
                if isChosen.[i] then 
                    yield A.[i] |]
printfn "%A" r

:)

答案 3 :(得分:1)

还有两种方法,只是为了展示(甚至)更多的F#库函数:

let A = [|1;2;3|]
let isChosen = [|true;false;true|]

let B = Seq.map2 (fun x b -> if b then Some x else None) A isChosen
        |> Seq.choose id
        |> Seq.toArray

let C = Array.foldBack2 (fun x b acc -> if b then x::acc else acc) A isChosen []
        |> List.toArray

我个人最喜欢的可理解性(因此可维护性):desco的回答

let r = [| for (v, f) in Seq.zip l f do if f then yield v|]