(** Extensions to the attribute list functions of module List. *) (** [replace lst tag newval] Replace or add an entry to an alist. *) let rec replace lst tag newval = match lst with [] -> [tag, newval] | (atag, aval) :: etc -> if atag = tag then (atag, newval) :: etc else (atag, aval) :: (replace etc tag newval) (** Merge a list of alists, with the first occurrence of each attribute taking precedence. Dang, it seems to work! *) let merge lst = List.fold_left (fun result alist -> (* Add elements of alist missing from result *) List.fold_left (fun result (a, v) -> if List.mem_assoc a result then result else (a, v) :: result) result alist) [] lst (** Strip any attributes present in a out of b *) let diff a b = (* was strip b a *) let a = List.map (fun (attr, _) -> attr) a in List.filter (fun (attr, _) -> not (List.mem attr a)) b (** Add a pair to an alist, but don't replace current value. *) let no_replace alist attr value = if List.mem_assoc attr alist then alist else (attr, value) :: alist (** Return a list of all values for an attribute. *) let assoc_all attr alist = List.map (fun (a, v) -> v) (List.filter (fun (a, v) -> a = attr) alist) let assoc_opt attr alist = try Some (List.assoc attr alist) with Not_found -> None let invert alist = List.map (fun (a, v) -> (v, a)) alist let enumerate lst = List2.enumerate lst let sort_car compare alist = List.sort (fun (a, _) (b, _) -> compare a b) alist let sort_cdr compare alist = List.sort (fun (_, a) (_, b) -> compare a b) alist let assoc = List.assoc let remove_assoc = List.remove_assoc let split = List.split