填写清单<list <>&gt;用f#</list <>

时间:2011-12-04 17:39:49

标签: list f#

我需要一个返回List&lt;的函数。列表&lt; T&GT;取代。 值i j应为1.0或2.0或无任何值......取决于某些条件(condition_1_is_true ...)。

我写了以下内容:

type T = 
  {
     value : float32
  }
let level_1_docked_balls : List<List<T>>=
    [ for i in 0 .. LineNumber - 1->
        [ for j  in 0 .. BallsPerLine - 1 ->

            if (condition_1_is_true) then
                {
                   value = 1.0f
                }
            elif (condition_2_is_true) then
                {
                    value = 2.0f
                }
            else
                //HERE I don't know how to return nothing

        ]
    ]

问题在于,在某些情况下(否则分支),我需要什么都不返回,但我不知道该怎么做。

注意:我知道最终有更好的方法来初始化List,但我想了解如何使上述示例有效。

1 个答案:

答案 0 :(得分:1)

您可能需要以下内容:

let level_1_docked_balls : List<List<option<float32>>> = 
    [ for i in 0 .. LineNumber - 1 -> 
        [ for j  in 0 .. BallsPerLine - 1 -> 
            if (condition_1_is_true) then Some 1.0f 
            elif (condition_2_is_true) then Some 2.0f 
            else None ]  ] 

没有办法说明列表中指定索引处有 nothing 。列表只是一个值列表,如果您没有返回值,则列表会更短。如果您想表示float或什么都不是,那么您可以使用F#option类型 - 值Some 1.0f指定值为1.0f且值None指定那个位置没有号码。

我还在类型注释中将类型从float更改为float32。类型float32对应System.Single,文字写为1.0f。另一个选项是double(float,文字为1.0)。

作为旁注,如果您要表示某些2D矩阵,特别是如果您需要访问指定索引处的值,那么使用2D数组可能会更好。尽管它们是可变的,但您可以使用诸如Array2D.map之类的高阶函数以不可变的方式使用它们。要创建类似于列表的2D数组,可以写:

let level1 = Array2D.init LineNumber BallsPerLine (fun i j ->
  if (condition_1_is_true) then Some 1.0f 
  elif (condition_2_is_true) then Some 2.0f 
  else None)

编辑有两种方法可以在游戏地图中表示像球一样的东西。使用密集表示,其中每个(i,j)都有一些值 - 这就是我之前描述的。另一种选择是使用稀疏表示,其中您只保留球的列表,以及球所在的(i,j)索引。然后你可以这样写:

let level_1_docked_balls : List<int * int * float32> = 
    [ for i in 0 .. LineNumber - 1 do
        for j  in 0 .. BallsPerLine - 1 do
          if (condition_1_is_true) then yield (i, j, 1.0f)
          elif (condition_2_is_true) then yield (i, j, 2.0f) ]

do循环中使用for时,您可以编写yield来生成元素,但不必在每个中返回一个值/ em> case - 没有else分支。但是,您需要知道值所属的索引。