退出/停止早期Array2D.initBased [英] Exit / stop Array2D.initBased early

查看:134
本文介绍了退出/停止早期Array2D.initBased的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这怎么可能提前退出/突围/停止在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函数。

我也贴的功能 F#片段用一个更好的格式的。

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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆