нужна помощь для чтения файла с определенным форматированным содержимым

#f#

#f#

Вопрос:

я использую F #. Я хочу решить какую-то проблему, которая требует от меня считывания входных данных из файла, но я не знаю, что делать. Первая строка в файле состоит из трех чисел, первые два числа — это x и y для отображения следующей строки. Пример файла:

 5 5 10
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
  

значение 5 5 10 — это следующая строка с картой 5×5, а 10 — это всего лишь несколько чисел, которые мне нужны для решения проблемы, следующим до конца строки является содержимое карты, которую я должен решить, используя 10, и я хочу сохранить номера этой карты в 2-мерном массиве. Кто-нибудь может помочь мне написать код для сохранения всех чисел из файла, чтобы я мог его обработать?
* Извините, мой английский плохой, надеюсь, мой вопрос можно понять 🙂

Ответ на мой собственный вопрос: Спасибо за ответ от Даниэля и Анкура. Для своей собственной цели я смешиваю код от вас обоих:

 let readMap2 (path:string) =
    let lines = File.ReadAllLines path
    let [|x; y; n|] = lines.[0].Split() |> Array.map int
    let data = 
        [| 
            for l in (lines |> Array.toSeq |> Seq.skip 1) do
                yield l.Split() |> Array.map int
        |]
    x,y,n,data
  

Большое спасибо: D

Ответ №1:

Вот несколько быстрых и грязных кодов. Он возвращает кортеж последнего числа в заголовке (в данном случае 10) и двумерный массив значений.

 open System.IO

let readMap (path:string) =
  use reader = new StreamReader(path)
  match reader.ReadLine() with
  | null -> failwith "empty file"
  | line -> 
    match line.Split() with
    | [|_; _; _|] as hdr -> 
      let [|x; y; n|] = hdr |> Array.map int
      let vals = Array2D.zeroCreate y x
      for i in 0..(y-1) do
        match reader.ReadLine() with
        | null -> failwith "unexpected end of file"
        | line -> 
          let arr = line.Split() |> Array.map int
          if arr.Length <> x then failwith "wrong number of fields"
          else for j in 0..(x-1) do vals.[i, j] <- arr.[j]
      n, vals
    | _ -> failwith "bad header"
  

Комментарии:

1. ах да, спасибо, извините, я кое-что забыл, я хочу сохранить содержимое карты в 2-мерном массиве, вы можете мне помочь

2. Я использовал неровный массив, потому что они работают лучше, но я обновил его, чтобы использовать двумерный.

Ответ №2:

В случае, если файл такой большой (никаких дополнительных данных для обработки) и всегда в правильном формате (нет необходимости обрабатывать недостающие данные и т.д.), Тогда это было бы так просто, как:

 let readMap (path:string) =
    let lines = File.ReadAllLines path
    let [|_; _; n|] = lines.[0].Split() |> Array.map int
    [| 
        for l in (lines |> Array.toSeq |> Seq.skip 1) do
            yield l.Split() |> Array.map int
    |]