Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

remove duplicate string and empty string

let undefined = ["string"; ""; "string"; "boolean";"";"innermost"]

I have a list and I want to write a function that return a list without duplicate and empty string list. For example the undefined list above will return :

["string"; "boolean"; "innermost"]

I write this function it return for me without duplicate but how can I add the condition with testing an empty string.

let rec uniquify = function
| [] -> []
| x::xs -> x :: uniquify (List.filter ((<>) x) xs)

Thank you very much

like image 482
Quyen Avatar asked Feb 17 '12 05:02

Quyen


People also ask

How do I remove duplicates without deleting blanks?

To remove duplicates keep blank rows, you need to add a helper column to identify the blank rows firstly, then apply Remove Duplicates function to remove the duplicates.


2 Answers

You can use a set of already seen strings:

module StringSet = Set.Make(String)
let uniquify list =
  let rec iter acc set list =
    match list with
     | [] -> List.rev acc
     | s :: tail ->
       if StringSet.mem s set then
          iter acc set tail
       else
          iter (s :: acc) (StringSet.add s set) tail
  in
  iter [] StringSet.empty list

The first line define the type of set of strings.

Then, uniquify calls an auxiliary function to either add a never seen string to both the list and the set, or just discard the string. The acc is used to make the iteration tail recursive (and thus, avoid stack overflows on long lists).

Using this scheme is better since the complexity is in O(N.log N) instead of N².

like image 186
Fabrice Le Fessant Avatar answered Oct 15 '22 09:10

Fabrice Le Fessant


Just pipe the result to List.filter (fun s -> s <> "") to remove the empty string afterwards. That's the simple, compositional way, yo u could also hack your function to drop it silently

let rec uniquify = function
| [] -> []
| x::xs ->
  (if x = "" then [] else [x]) @ uniquify (List.filter ((<>) x) xs)

Note that your function is quadratic, you can have better complexity by sorting the list first, or by converting to a set and back. Batteries has functions to do that for you.

let do_stuff list =
  let open Batteries in
  List.remove (List.sort_unique String.compare list) ""
like image 21
gasche Avatar answered Oct 15 '22 07:10

gasche