问题描述
这怎么可能提前退出/突围/停止在F#数组创建(在这种情况下, Array2D.initBased
)的?
的注:的 DIC
是词典<,>()
,其值是一个对象,有一个名为的someMethod
的方法,它有两个 INT
参数。
让ARR = Array2D.initBased 1×宽×高(乐趣x和y - >
让distinctValues = DIC |> Seq.map(FUN(键值(K,V)) - > v.someMethod x和y)|> Set.ofSeq
匹配distinctValues.count与
| dic.Count - >
// 做一点事
//退出阵列创建这里,因为我不需要任何改编更多,如果v.someMethod x和y产生不同的值对每个DIC值
| _ - >
//做别的事情
这是一个棘手的问题 - 我不认为有,让你轻松做到这一点的任何功能。我认为最好的办法可能是定义一个隐藏的行为自己的高阶函数(使用不是很优雅的递归实现)。
这个想法是定义 tryInitBased
行为类似 initBased
但用户提供的函数可以返回选项(来表示失败)和函数返回的选项(无论成功创建数组或无
)
///尝试初始化使用指定的基本偏移量和长度的二维数组。
///所提供的功能,可以返回无来表示失败 - 如果初始化
///失败为任何阵列内的位置,施工停止并
///在函数返回无。
让tryInitBased BASE1 BASE2长度1长度2 F =
让ARR = Array2D.createBased BASE1 BASE2长度1长度2(Unchecked.defaultof< _>)
///递归函数填充一个指定的X线
///(返回false尽快为'F'的任何调用失败,或真)
让REC菲伊X Y =
如果y< (BASE2 +长度2),然后
比赛˚FX Y与
|一些v - 输出>
。ARR [X,Y]< - v
菲伊X(Y + 1)
| _ - >假
否则返回true
该遍历所有'x'的位置///递归函数
///并呼吁'雌',以填补各行
让REC fillX X =
如果x< (BASE1 +长度1),然后
如果雌点¯xBASE2然后fillX(X + 1)
否则返回false
否则返回true
如果fillX BASE1那么一些其他编曲无
然后你就可以保持你的code pretty大致相同,但替换 initBased
与 tryInitBased
并返回无
或部分(RES)
从lambda函数。
我也贴的功能的。
How is it possible to exit early / break out of / stop an array creation in F# (in this case, of Array2D.initBased
)?
Remark: dic
is a Dictionary<,>()
whose value is an object that has a method named someMethod
that takes two int
parameters.
let arr = Array2D.initBased 1 1 width height (fun x y ->
let distinctValues = dic |> Seq.map (fun (KeyValue(k,v)) -> v.someMethod x y) |> Set.ofSeq
match distinctValues.count with
| dic.Count ->
// do something
// exit array creation here, because I do not need arr any more if v.someMethod x y produced distinct values for each dic value
| _ ->
// do something else
This is a tricky question - I don't think there is any function that lets you do this easily. I think the best option is probably to define your own higher-order function (implemented using not very elegant recursion) that hides the behavior.
The idea would be to define tryInitBased
that behaves as initBased
but the user-provided function can return option (to indicate failure) and the function returns option (either successfully created array or None
):
/// Attempts to initialize a 2D array using the specified base offsets and lengths.
/// The provided function can return 'None' to indicate a failure - if the initializer
/// fails for any of the location inside the array, the construction is stopped and
/// the function returns 'None'.
let tryInitBased base1 base2 length1 length2 f =
let arr = Array2D.createBased base1 base2 length1 length2 (Unchecked.defaultof<_>)
/// Recursive function that fills a specified 'x' line
/// (returns false as soon as any call to 'f' fails, or true)
let rec fillY x y =
if y < (base2+length2) then
match f x y with
| Some v ->
arr.[x, y] <- v
fillY x (y + 1)
| _ -> false
else true
/// Recursive function that iterates over all 'x' positions
/// and calls 'fillY' to fill individual lines
let rec fillX x =
if x < (base1+length1) then
if fillY x base2 then fillX (x + 1)
else false
else true
if fillX base1 then Some arr else None
Then you can keep your code pretty much the same, but replace initBased
with tryInitBased
and return None
or Some(res)
from the lambda function.
I also posted the function to F# snippets with a nicer formatting.
这篇关于退出/停止早期Array2D.initBased的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!