package janestreet_csv

  1. Overview
  2. Docs

Source file csv_grid.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
open Core
open Poly
open Csv_common
module Time = Time_float_unix

let grid ~field ~start ~stop ~step csv =
  match List.findi csv.header ~f:(fun _idx elem -> elem = field) with
  | None -> failwithf "unable to find csv field %s" field ()
  | Some (field_idx, _) ->
    let num_times =
      Time.Span.( // ) (Time.diff stop start) step |> Float.iround_down_exn
    in
    let grid_times =
      List.init num_times ~f:(fun i ->
        Time.add start (Time.Span.scale step (Float.of_int (i + 1))))
    in
    let dummy_line = Array.create ~len:(List.length csv.header) "" in
    let old_lines = List.map csv.lines ~f:Array.of_list |> Array.of_list in
    let old_times =
      Array.map old_lines ~f:(fun old_line -> Time.of_string old_line.(field_idx))
    in
    let rec increment_to_max_on_or_before_grid_time i grid_time =
      if Time.( < ) grid_time old_times.(i)
      then i - 1
      else if i = Array.length old_times - 1
      then i
      else increment_to_max_on_or_before_grid_time (i + 1) grid_time
    in
    let lines =
      List.fold grid_times ~init:(0, []) ~f:(fun (prior_line_idx, l) grid_time ->
        let new_idx = increment_to_max_on_or_before_grid_time prior_line_idx grid_time in
        if new_idx < 0
        then (
          let add_line = Array.copy dummy_line in
          add_line.(field_idx) <- Time.to_string grid_time;
          0, add_line :: l)
        else (
          let add_line = Array.copy old_lines.(new_idx) in
          add_line.(field_idx) <- Time.to_string grid_time;
          new_idx, add_line :: l))
      |> snd
      |> List.map ~f:Array.to_list
      |> List.rev
    in
    { header = csv.header; lines }
;;

let run ?separator ~field ~start ~stop ~step file =
  Or_file.with_all ?separator file ~f:(fun csv ->
    csv
    |> Csv_sort.sort_on_fields [ { field; order = Ascending; sort_type = Time } ]
    |> grid ~field ~start ~stop ~step
    |> print_csv ?separator)
;;
OCaml

Innovation. Community. Security.