Algorithm 优雅的数组。多点(?)实现

Algorithm 优雅的数组。多点(?)实现,algorithm,f#,functional-programming,ocaml,Algorithm,F#,Functional Programming,Ocaml,我想实现类似于虚构的数组的东西。多点: Array.multipick : choosers:('a -> bool) [] -> array:'a [] -> 'a [] 在内部,我们使用所有选择器测试每个数组的元素,第一个返回true的选择器将从选择器数组中删除,并将该选择器的参数添加到结果中。之后,我们继续交互,而选择器数组中还有元素 最后一部分很重要,因为没有提前退出的要求,这可以通过使用Array.fold来解决 这可以通过以下方式轻松实现: let rec imp

我想实现类似于虚构的
数组的东西。多点

Array.multipick : choosers:('a -> bool) [] -> array:'a [] -> 'a []
在内部,我们使用所有
选择器测试每个数组的元素,第一个返回
true
选择器将从
选择器
数组中删除,并将该
选择器
的参数添加到结果中。之后,我们继续交互,而
选择器
数组中还有元素

最后一部分很重要,因为没有提前退出的要求,这可以通过使用Array.fold来解决

这可以通过以下方式轻松实现:

let rec impl currentIndex currentChoosers results

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

使用大小不断变化的数组编写优雅的代码是相当困难的。下面是一些在列表上工作的代码,它们不会改变任何值

let rec pick accum elem tried = function
    | [] -> (accum, List.rev tried)
    | chooser :: rest ->
        if chooser elem then (elem :: accum, List.rev_append tried rest)
        else pick accum elem (chooser :: tried) rest

let rec multipick_l accum choosers list =
    match choosers, list with
    | [], _
    | _, [] -> List.rev accum
    | _, elem :: elems ->
        let (accum', choosers') = pick accum elem [] choosers in
        multipick_l accum' choosers' elems

let multipick choosers array =
    Array.of_list
        (multipick_l [] (Array.to_list choosers) (Array.to_list array))

如果您认为除了提前退出要求之外,
Array.fold\u left
是可用的,那么可以使用异常提前退出。

使用大小不断变化的数组编写优雅的代码是相当困难的。下面是一些在列表上工作的代码,它们不会改变任何值

let rec pick accum elem tried = function
    | [] -> (accum, List.rev tried)
    | chooser :: rest ->
        if chooser elem then (elem :: accum, List.rev_append tried rest)
        else pick accum elem (chooser :: tried) rest

let rec multipick_l accum choosers list =
    match choosers, list with
    | [], _
    | _, [] -> List.rev accum
    | _, elem :: elems ->
        let (accum', choosers') = pick accum elem [] choosers in
        multipick_l accum' choosers' elems

let multipick choosers array =
    Array.of_list
        (multipick_l [] (Array.to_list choosers) (Array.to_list array))

如果您认为除了提前退出要求之外,
Array.fold\u left
是可用的,那么您可以使用异常提前退出。

提前退出的折叠是一个好主意,但是专门针对阵列的具有生产价值的折叠需要以非常必要的方式编写。为了简单起见,我将从中获取更一般的序列

我使用数组索引键控的
Map
来跟踪剩余函数-这允许轻松删除元素,但仍然保留它们的顺序(因为在迭代时Map键值对是按键排序的)


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

提前退出是一个好主意,但是专门针对阵列的具有生产价值的折叠需要以相当必要的方式编写。为了简单起见,我将从中获取更一般的序列

我使用数组索引键控的
Map
来跟踪剩余函数-这允许轻松删除元素,但仍然保留它们的顺序(因为在迭代时Map键值对是按键排序的)


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

谢谢你的回答!我将尝试实现类似
set的功能谢谢你的回答!我将尝试实现类似于
Setyeah的东西,我已经想到了类似的smth!另外,lazy-Seq.scan+Seq.takeWhile组合非常简洁。是的,我已经想到了类似的smth!另外,lazy-Seq.scan+Seq.takeWhile组合非常简洁。