I'm trying to learn functional programming and having difficulty expressing a file parsing task functionally. Let's say I have a text file with the following format:
val_0: <--- "header"
key_0_0 <--- these keys should be set to the "header" or val0
key_0_1
key_0_2
...
...
val_n:
...
key_n_m
How can I end up with a hash table with all keys set to their associated value?
EDIT: My solution. Can anyone improve it?
open Core.Std
let contains s1 s2 =
let re = Str.regexp_string s2 in
try ignore (Str.search_forward re s1 0); true
with Not_found -> false
let read_db f =
let tbl = Caml.Hashtbl.create 123456 in
let lines = In_channel.read_lines f in
let src = ref "" in
List.iter ~f:(fun g -> if contains g ":" then src := else Caml.Hashtbl.add tbl g !src) lines;
tbl
Here's my solution, just for comparison.
let line_opt ic =
try Some (input_line ic) with End_of_file -> None
let fold_lines_in f init fn =
let ic = open_in fn in
let rec go accum =
match line_opt ic with
| None -> accum
| Some line -> go (f accum line)
in
let res = go init in
close_in ic;
res
let hashtable_of_file fn =
let ht = Hashtbl.create 16 in
let itab label line =
let len = String.length line in
if line.[len - 1] = ':' then
String.sub line 0 (len - 1)
else
let () = Hashtbl.add ht line label in
label
in
let _ = fold_lines_in itab "" fn in
ht
Update
(Fixed non-tail-recursive fold implementation, sorry.)