Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F#使用while循环_F# - Fatal编程技术网

F#使用while循环

F#使用while循环,f#,F#,我有一个datareader,我想返回其中的行集合,在读了一天的书之后,我无法找到用f#实现它的最佳方法。我可以用普通的C#方式用F#完成,但这不是我使用F的原因# 以下是我正在努力实现的目标 let values = while reader.Read() do yield reader.GetString(0), reader.GetInt64(1) 以上就是我试图做的 所有值都被收集到值中,这些值可以是字典、元组或任何集合 在while循环中不能使用yield,

我有一个datareader,我想返回其中的行集合,在读了一天的书之后,我无法找到用f#实现它的最佳方法。我可以用普通的C#方式用F#完成,但这不是我使用F的原因#

以下是我正在努力实现的目标

let values =
    while reader.Read() do
        yield reader.GetString(0), reader.GetInt64(1)
以上就是我试图做的

  • 所有值都被收集到值中,这些值可以是字典、元组或任何集合
  • 在while循环中不能使用yield,但这正是我要做的

实现这一点的最佳方法是什么?您可以使用序列表达式实现枚举数:

let records = seq { while reader.NextResult() do yield (reader.GetString(0), reader.GetInt64(1)) }
如果需要两个以上的字段,可以生成列索引(或名称)->字段值(未测试代码)的映射:

让dbSchema=reader.GetSchemaTable()
let makeMap(rdr:IDataReader)(模式:DataTable)=
schema.Columns |>Seq.cast |>Seq.map(fun col->(col.ColumnName,rdr.[col.ColumnName]))|>map.ofSeq
让records=seq{while reader.NextResult()不产生(makeMap reader dbSchema)}

对于此类任务,我想首先将输入转换为字符串序列

.Net 4.0提供读取行,其返回值的类型为
seq

在.Net的较低版本中,需要实现以下功能:

   let readLines filePath = seq {
    use sr = new StreamReader (filePath)
    while not sr.EndOfStream do
     yield sr.ReadLine ()
   }

我们这里不讨论文件,但是,在早期的.NET版本中,您可以(使用小文件):

其中,
reader
是文本阅读器。

F#还提供数组和序列的列表理解

let records_as_list = 
    [
        while reader.Read() 
            do yield (reader.GetString(0), reader.GetInt64(1)) 
    ]

let records_as_array = 
    [|
        while reader.Read() 
            do yield (reader.GetString(0), reader.GetInt64(1)) 
    |]

let records_as_sequence = 
    seq {
        while reader.Read() 
            do yield (reader.GetString(0), reader.GetInt64(1)) 
    }
F#内置了一个方便的字典功能,名为
dict

let records_as_IDictionary = dict records_as_sequence

我可以通过向
IDataReader
添加一个扩展属性来更一般地处理这个问题,该属性将任何数据读取器转换为
seq

[<AutoOpen>]
module DataReaderEx =
    open System.Data

    type IDataReader with
        member this.toSeq =
            seq { while this.Read() do yield this :> IDataRecord }

如果文件很大,则应避免读取所有内容和拆分。在这个问题中,
reader
实际上是一个IDataReader,而不是TextReaderies,基本思想是一样的。seq的问题是它会延迟加载,所以在这种情况下,当您想要阅读它时,阅读器会通过在最后一行添加|>seq.toList来实现集合,从而彻底修复。
let records_as_list = 
    [
        while reader.Read() 
            do yield (reader.GetString(0), reader.GetInt64(1)) 
    ]

let records_as_array = 
    [|
        while reader.Read() 
            do yield (reader.GetString(0), reader.GetInt64(1)) 
    |]

let records_as_sequence = 
    seq {
        while reader.Read() 
            do yield (reader.GetString(0), reader.GetInt64(1)) 
    }
let records_as_IDictionary = dict records_as_sequence
[<AutoOpen>]
module DataReaderEx =
    open System.Data

    type IDataReader with
        member this.toSeq =
            seq { while this.Read() do yield this :> IDataRecord }
reader.toSeq
|> Seq.map (fun row -> row.GetString(0), row.GetInt64(1))