OCaml - 将csv文件读入数组

时间:2015-02-26 00:23:41

标签: arrays csv ocaml

我正在尝试将OCaml中的csv文件导入到数组中。我确实认识到这不是最适合这种语言的,我不确定阵列是最好的结构,但无论如何...... 它工作正常,但我对我的方式感到非常不安。

let import file_name separator =
  let reg_separator = Str.regexp separator in
  let value_array = Array.make_matrix 1600 12 0. in
  let i = ref 0 in
  try
    let ic = open_in file_name in
    (* Skip the first line, columns headers *)
    let _ = input_line ic in
    try
      while true; do
        (* Create a list of values from a line *)
        let line_list = Str.split reg_separator (input_line ic) in
        for j = 0 to ((List.length line_list) - 1) do
          value_array.(!i).(j) <- float_of_string (List.nth line_list j)
        done;
        i := !i + 1
      done;
      value_array
    with 
      | End_of_file -> close_in ic; value_array
    with
      | e -> raise e;;

基本上,我逐行读取文件,然后沿分隔符分割每一行。问题是这会返回一个列表,因此下一行的复杂性真的很糟糕 value_array.(!i).(j) <- float_of_string (List.nth line_list j)
有没有办法以更好的方式做到这一点,而不是自己重新编码整个分裂的东西?

PS:我很长时间没有使用Ocaml进行编码,所以我对尝试的事情以及返回数组的方式都不太了解。

干杯。

1 个答案:

答案 0 :(得分:2)

在OCaml >=4.00.0上,您可以使用List.iteri函数。

List.iteri
  (fun j elem -> value_array.(!i).(j) <- float_of_string elem)
  line_list

您可以使用此代码替换for循环,它应该可以很好地工作(当然,您需要保留;)。

在旧版本的OCaml上,您可以将List.iter与您手动增加的引用一起使用,或者以更干净的方式声明您自己的iteri。

请注意,您的代码不是很安全,尤其是文件大小(例如,行数和列数)。也许您应该将维度参数作为函数参数,以获得一点灵活性。

编辑:对于未来的读者,您可以使用非常简单的ocaml-csv(通过OPAM:opam install csv