代码之家  ›  专栏  ›  技术社区  ›  James Black

如何在大小未知的情况下使用while..do循环初始化F#list

  •  2
  • James Black  · 技术社区  · 14 年前

    while..do 循环遍历读取器,结果应该是某个类型的列表。

    (fun(reader) ->
                [
                    while reader.Read() do
                        new CityType(Id=(reader.GetInt32 0), Name=(reader.GetString 1), StateName=(reader.GetString 2))
                ])
    

    This expression should have type 'unit', but has type 'CityType'. Use 'ignore' to discard the result of the expression, or 'let' 
    to bind the result to a name.
    

    那么,迭代DataReader并创建列表的最佳方法是什么?

    2 回复  |  直到 14 年前
        1
  •  9
  •   Yin Zhu    14 年前

    您可以使用列表理解:

    [
       while reader.Read() do
           let d =  new CityType(Id=(reader.GetInt32 0), Name=(reader.GetString 1), StateName=(reader.GetString 2))
           yield d
    ]
    

    这里还有一个例子:

    /// The squares of the first 10 integers
    let squaresOfOneToTen = [ for x in 0..10 -> x*x ]
    

    let squaresOfOneToTen = [ for x in 0..10 do yield x*x ]
    

    seq { 
       for i=1 to 9 do 
          for j=1 to 9 do
             yield (i,j,i*j)
    }
    
    
    [| for i=1 to 100 do yield i*i |]
    

    也可以在序列中生成子序列( yield! ),下面是一个使用 Project Euler 31 .

        2
  •  6
  •   Tomas Petricek    14 年前

    在方括号中 [ ... ]

    列出文字

    [ 1; 2; 3; ]       // list of constant expressions
    [ 1+1; 2+2; 3+3 ]  // creates list [ 2; 4; 6 ]
    

    列表解析 当您有一些代码执行某些操作并生成元素列表(通过在计算期间生成元素)时使用。这就是殷珠在回答时所用的。例如:

    [ yield 1; ]           // generates singleton list [ 1 ] 
    [ yield 1; yield 2; ]  // generates list with two elements
    [ for x in 1 .. 10 do  // iterates loop 10 times
        yield x * x ]      // ... generates element during every iteration
    

    高级功能
    你也可以使用 yield! 一次生成多个元素:

    [ yield! [ 1; 2 ]      // generates a list containing [ 1; 2; 3; 4 ]
      yield! [ 3; 4 ] ]
    

    这可以用于编写递归函数,因此可以使用递归而不是循环重写代码(如果需要保持某种状态,这会很有用,但由于代码当前的外观, while

    let rec loop reader = 
      [ if reader.Read() then
          yield new CityType(Id=(reader.GetInt32 0), Name=(reader.GetString 1), 
                             StateName=(reader.GetString 2))   
          yield! loop reader ]
    

    这是一种经常出现在列表理解中的模式,因此了解它很有用:-)。