开发者

how to read file with multiple record

this is similiar to my previous question: but here is some improvisation:

3 4 5
aaaaa
aaaaa
aaaaa
aaaaa

bbbbb
bbbbb
bbbbb
bbbbb

ccccc
ccccc
ccccc
cc开发者_开发百科ccc

1 2 3
aaa
aaa

the first number is the level, the second is the row and the third is the column, i want to insert all the data (the character) into three dimensional Array. How is the code?

Thanks for the help :)


The function crunch reads a text file in the format you described and converts it into a sequence of 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 -> ()
    } 


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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜