我想实现类似于虚构的东西Array.multipick
:
Array.multipick : choosers:('a -> bool) [] -> array:'a [] -> 'a []
在内部,我们使用all测试每个数组的元素,要返回choosers
的第一个元素从数组中删除,然后将的参数添加到结果中。之后,我们继续进行交互,同时array剩下了element。chooser
true
choosers
chooser
choosers
最后一部分很重要,因为无需提前退出就可以用just解决Array.fold
。
这很容易实现,例如:
let rec impl currentIndex currentChoosers results
但这对我来说太程序化了。也许还有更优雅的解决方案?
提早退出的弃牌是个好主意,但是,必须以相当必要的方式编写值得生产的,专门针对目标的阵列。为了简单起见,我将从这个答案中获取更通用的序列一。
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] 删除。
我来说两句