4

Is there a library function to find List1 minus elements that appear in List2? I've been googling around and haven't found much.

It doesn't seem too trivial to write it myself. I've written a function to remove a specific element from a list but that's much more simple:

let rec difference l arg = match l with
| [] -> []
| x :: xs -> 
    if (x = arg) then difference xs arg
    else x :: difference xs arg;;
Jackson Tale
  • 25,428
  • 34
  • 149
  • 271
Collin
  • 1,777
  • 4
  • 26
  • 42
  • 1
    There is Set [diff](http://caml.inria.fr/pub/docs/manual-ocaml/libref/Set.S.html), but that doesn't maintain ordering or multiplicity. – user2864740 Mar 02 '14 at 19:45

2 Answers2

9

Will this do?

let diff l1 l2 = List.filter (fun x -> not (List.mem x l2)) l1
Jackson Tale
  • 25,428
  • 34
  • 149
  • 271
  • This computes the intersection of the lists. You are missing `not`, I think. (This is probably an assignment, so no harm done really.) – Jeffrey Scofield Mar 02 '14 at 20:18
  • @JeffreyScofield yeah, didn't know that `-` was dash, I thought it was some kind of indicator. edited my answer and the question – Jackson Tale Mar 02 '14 at 20:37
2

What I ended up actually doing was just writing another function which would call the first one I posted

let rec difference l arg = match l with
    | [] -> []
    | x :: xs -> 
        if (x = arg) then difference xs arg
        else x :: difference xs arg;; 

let rec list_diff l1 l2 = match l2 with
    | [] -> l1
    | x :: xs -> list_diff (difference l1 x) xs;;

Although the solution I accepted is much more elegant

Collin
  • 1,777
  • 4
  • 26
  • 42
  • This soultions doesn't seem to be completely correct. This only finds what is not in list 1 (l1). That is, list_diff [3;4;5] [2;3;6];; returns [4; 5] not [4;5;6] – sgsweb Feb 22 '19 at 14:02