优雅的Array.multipick(?)实现

yuyoyuppe

我想实现类似于虚构的东西Array.multipick

Array.multipick : choosers:('a -> bool) [] -> array:'a [] -> 'a []

在内部,我们使用all测试每个数组的元素,要返回choosers的第一个元素数组中删除,然后将的参数添加到结果中。之后,我们继续进行交互,同时array剩下了elementchoosertruechooserschooserchoosers

最后一部分很重要,因为无需提前退出就可以用just解决Array.fold

这很容易实现,例如:

let rec impl currentIndex currentChoosers results

但这对我来说太程序化了。也许还有更优雅的解决方案?

r

提早退出的弃牌是个好主意,但是,必须以相当必要的方式编写值得生产的,专门针对目标的阵列。为了简单起见,我将从这个答案中获取更通用的序列一

let multipick (choosers: ('a -> bool) array) (arr: 'a array) : 'a array =
    let indexed =
        choosers
        |> Seq.indexed
        |> Map.ofSeq
    ((indexed, []), arr)
    ||> foldWhile (fun (cs, res) e ->
        if Map.isEmpty cs then
            None
        else
            match cs |> Seq.tryFind (fun kvp -> kvp.Value e) with
            | Some kvp -> Some (Map.remove kvp.Key cs, e :: res)
            | None     -> Some (cs, res))
    |> snd
    |> List.rev
    |> Array.ofList

我正在使用Map按数组索引键来跟踪其余函数-这样可以轻松删除元素,但仍保留其顺序(因为映射键值对在迭代时按键排序)。

Set由于比较约束,F#无法使用函数。System.Collections.Generic.HashSet可以工作,但是它是可变的,并且我不确定它是否会保留顺序。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章