如何读取多条记录的文件

时间:2011-10-07 05:00:39

标签: f#

这与我的previous问题类似: 但这是一些即兴创作:

3 4 5
aaaaa
aaaaa
aaaaa
aaaaa

bbbbb
bbbbb
bbbbb
bbbbb

ccccc
ccccc
ccccc
ccccc

1 2 3
aaa
aaa

第一个数字是级别,第二个是行,第三个是列,我想将所有数据(字符)插入到三维数组中。代码怎么样?

感谢您的帮助:)

2 个答案:

答案 0 :(得分:1)

函数crunch以您描述的格式读取文本文件,并将其转换为Array3D序列。

open System
open System.IO

// if .Net 4.0 use this:
// let isEmpty (s:string) = String.IsNullOrWhiteSpace(s)
let isEmpty (s:string) = String.IsNullOrEmpty(s) || s.Trim().Length = 0

let readNonEmptyLine (reader:StreamReader) =
    let mutable line = ""
    while (not reader.EndOfStream) && isEmpty line do 
        line <- reader.ReadLine()
    if (isEmpty line && reader.EndOfStream) then None else Some(line)

let crunch (path:string) = seq {
    use reader = new StreamReader(path)
    while not reader.EndOfStream do
        match readNonEmptyLine reader with
        | Some line ->
          let [|blocks;rows;cols|] = line.Split() |> Array.map int
          let array3D = Array3D.zeroCreate blocks rows cols
          for b in 0..blocks-1 do
              for r in 0..rows-1 do
                  let row = readNonEmptyLine reader
                  for c in 0..cols-1 do
                      array3D.[b,r,c] <- row.Value.[c]
          yield array3D
        | None -> ()
    } 

答案 1 :(得分:0)

open System
open System.IO

let lineSeq (path:string) =
  seq {
    use r = new StreamReader(path)
    while not r.EndOfStream do
      yield r.ReadLine()
  }

let strToArray (s:string) = s.Split([|' ';'\t'|], StringSplitOptions.RemoveEmptyEntries)

let make3DArray sq =
  let rec aux sq acc = 
    if Seq.isEmpty sq
    then List.toArray acc |> Array.rev
    else
      let [| level; row; col |] = Seq.head sq |> strToArray |> Array.map int
      let sq = Seq.skip 1 sq
      let ar = Array3D.zeroCreate<char> level row col
      let block = Seq.take (level * row) sq
      let sq = Seq.skip (level * row) sq
      Seq.iteri (fun r line -> Seq.iteri (fun c  ch ->ar.[r / row, r % row, c] <- ch ) line ) block
      aux sq (ar::acc)
  aux sq []

let data =
  lineSeq "data.txt"
  |> Seq.filter (fun s -> "" <> s.Trim())
  |> make3DArray