From 6d2dc4ccf44628a5453ff8a79c677c1e01c9802e Mon Sep 17 00:00:00 2001 From: favonia Date: Sat, 22 May 2021 21:27:35 -0500 Subject: [PATCH] feat(list): add the optional argument all to sorted_remove Also added another missing "since". --- src/core/CCList.ml | 49 ++++++++++++++++++++++++++++----------- src/core/CCList.mli | 4 +++- src/core/CCListLabels.mli | 9 ++++--- 3 files changed, 45 insertions(+), 17 deletions(-) diff --git a/src/core/CCList.ml b/src/core/CCList.ml index ca6ab2f9..62455198 100644 --- a/src/core/CCList.ml +++ b/src/core/CCList.ml @@ -825,28 +825,51 @@ let sorted_insert ~cmp ?(uniq=false) x l = List.mem x (sorted_insert ~cmp:CCInt.compare x l)) *) -let sorted_remove ~cmp ~key l = - let rec aux cmp key left l = match l with +let sorted_remove ~cmp ?(all=false) x l = + let rec aux cmp all x left l = match l with | [] -> List.rev left | y :: tail -> - match cmp key y with - | 0 -> aux cmp key left tail + match cmp x y with + | 0 -> + if all then aux cmp all x left tail else List.rev_append left tail | n when n<0 -> List.rev_append left l - | _ -> aux cmp key (y::left) tail + | _ -> aux cmp all x (y::left) tail in - aux cmp key [] l + aux cmp all x [] l (*$Q - Q.(pair small_int (list small_int)) (fun (key,l) -> \ + Q.(pair small_int (list small_int)) (fun (x,l) -> \ let l = List.sort Stdlib.compare l in \ - is_sorted ~cmp:CCInt.compare (sorted_remove ~cmp:CCInt.compare ~key l)) - Q.(pair small_int (list small_int)) (fun (key,l) -> \ + is_sorted ~cmp:CCInt.compare (sorted_remove ~cmp:CCInt.compare x l)) + Q.(pair small_int (list small_int)) (fun (x,l) -> \ let l = List.sort Stdlib.compare l in \ - let l' = sorted_remove ~cmp:CCInt.compare ~key l in \ - List.length l' = List.length l - count (CCInt.equal key) l) - Q.(pair small_int (list small_int)) (fun (key,l) -> \ + is_sorted ~cmp:CCInt.compare (sorted_remove ~cmp:CCInt.compare ~all:false x l)) + Q.(pair small_int (list small_int)) (fun (x,l) -> \ let l = List.sort Stdlib.compare l in \ - not (List.mem key (sorted_remove ~cmp:CCInt.compare ~key l))) + is_sorted ~cmp:CCInt.compare (sorted_remove ~cmp:CCInt.compare ~all:true x l)) + Q.(pair small_int (list small_int)) (fun (x,l) -> \ + let l = List.sort Stdlib.compare l in \ + let l' = sorted_remove ~cmp:CCInt.compare x l in \ + List.length l' = List.length l - (if List.mem x l then 1 else 0)) + Q.(pair small_int (list small_int)) (fun (x,l) -> \ + let l = List.sort Stdlib.compare l in \ + let l' = sorted_remove ~cmp:CCInt.compare ~all:true x l in \ + List.length l' = List.length l - count (CCInt.equal x) l) + Q.(pair small_int (list small_int)) (fun (x,l) -> \ + let l = List.sort Stdlib.compare l in \ + let l' = sorted_remove ~cmp:CCInt.compare ~all:false x l in \ + List.length l' = List.length l - (if List.mem x l then 1 else 0)) + Q.(pair small_int (list small_int)) (fun (x,l) -> \ + let l = List.sort Stdlib.compare l in \ + let l' = sorted_remove ~cmp:CCInt.compare x l in \ + count (CCInt.equal x) l' = count (CCInt.equal x) l - (if List.mem x l then 1 else 0)) + Q.(pair small_int (list small_int)) (fun (x,l) -> \ + let l = List.sort Stdlib.compare l in \ + let l' = sorted_remove ~cmp:CCInt.compare ~all:false x l in \ + count (CCInt.equal x) l' = count (CCInt.equal x) l - (if List.mem x l then 1 else 0)) + Q.(pair small_int (list small_int)) (fun (x,l) -> \ + let l = List.sort Stdlib.compare l in \ + not (List.mem x (sorted_remove ~cmp:CCInt.compare ~all:true x l))) *) let uniq_succ ~eq l = diff --git a/src/core/CCList.mli b/src/core/CCList.mli index f9dd799f..921a7e22 100644 --- a/src/core/CCList.mli +++ b/src/core/CCList.mli @@ -528,9 +528,11 @@ val sorted_insert : cmp:('a -> 'a -> int) -> ?uniq:bool -> 'a -> 'a list -> 'a l [x] is not duplicated. Default [false] ([x] will be inserted in any case). @since 0.17 *) -val sorted_remove : cmp:('a -> 'a -> int) -> key:'a -> 'a list -> 'a list +val sorted_remove : cmp:('a -> 'a -> int) -> ?all:bool -> 'a -> 'a list -> 'a list (** [sorted_insert ~cmp ~key l] removes [key] from a sorted list [l] such that the return value is sorted too. + @param all if true then all occurrences of [x] will be removed. Otherwise, only the first + [x] will be removed (if any). Default [false] (only the first will be removed). @since NEXT_RELEASE *) val uniq_succ : eq:('a -> 'a -> bool) -> 'a list -> 'a list diff --git a/src/core/CCListLabels.mli b/src/core/CCListLabels.mli index 7091df9c..d55f1ecc 100644 --- a/src/core/CCListLabels.mli +++ b/src/core/CCListLabels.mli @@ -507,7 +507,8 @@ val sorted_merge : cmp:(('a -> 'a -> int) [@keep_label]) -> 'a list -> 'a list - val sorted_diff : cmp:(('a -> 'a -> int) [@keep_label]) -> 'a list -> 'a list -> 'a list (** [sorted_merge ~cmp l1 l2] returns the elements in [l1] that are not in [l2]. Both lists are assumed to be sorted with respect to [cmp] and - duplicate elements are treated individually. *) + duplicate elements are treated individually. + @since NEXT_RELEASE *) val sort_uniq : cmp:(('a -> 'a -> int) [@keep_label]) -> 'a list -> 'a list (** [sort_uniq ~cmp l] sorts the list [l] using the given comparison function [cmp] @@ -530,9 +531,11 @@ val sorted_insert : cmp:(('a -> 'a -> int) [@keep_label]) -> ?uniq:bool -> 'a -> [x] is not duplicated. Default [false] ([x] will be inserted in any case). @since 0.17 *) -val sorted_remove : cmp:(('a -> 'a -> int) [@keep_label]) -> key:('a [@keep_label]) -> 'a list -> 'a list -(** [sorted_insert ~cmp ~key l] removes [key] from a sorted list [l] such that +val sorted_remove : cmp:(('a -> 'a -> int) [@keep_label]) -> ?all:bool -> 'a -> 'a list -> 'a list +(** [sorted_insert ~cmp x l] removes [x] from a sorted list [l] such that the return value is sorted too. + @param all if true then all occurrences of [x] will be removed. Otherwise, only the first + [x] will be removed (if any). Default [false] (only the first will be removed). @since NEXT_RELEASE *) val uniq_succ : eq:(('a -> 'a -> bool) [@keep_label]) -> 'a list -> 'a list