2012-02-17 11 views
5
let undefined = ["string"; ""; "string"; "boolean";"";"innermost"] 

Ho una lista e voglio scrivere una funzione che restituisca una lista senza lista di stringhe doppia e vuota. Per esempio la lista undefined precedente restituirà:rimuovere la stringa duplicata e la stringa vuota

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

scrivo questa funzione tornare per me senza duplicati, ma come posso aggiungere la condizione di testare una stringa vuota.

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

La ringrazio molto

risposta

5

Proprio pipe il risultato a List.filter (fun s -> s <> "") per rimuovere la stringa vuota dopo. Questo è il modo semplice, compositiva, yo u potrebbe anche incidere il vostro funzione per farlo cadere silenziosamente

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

Nota che la funzione è quadratica, si può avere meglio la complessità di classificare la lista prima, o convertendo per un set e indietro. Batteries ha delle funzioni per farlo.

let do_stuff list = 
    let open Batteries in 
    List.remove (List.sort_unique String.compare list) "" 
7

è possibile utilizzare un insieme di stringhe già visti:

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 

La prima linea di definire il tipo di insieme di stringhe.

Quindi, uniquify chiama una funzione ausiliaria per aggiungere una stringa mai vista sia alla lista che al set, o semplicemente scartare la stringa. Il codice acc viene utilizzato per rendere ricorsivo l'iteration tail (e quindi evitare lo stack overflow nelle lunghe liste).

L'utilizzo di questo schema è migliore poiché la complessità è in O (N.log N) anziché N².

+0

@Febrice Le Fessant Ho provato il tuo codice e alla riga 8 (iter s set tail) il compilatore mi ha dato questo errore: Errore: "Questa espressione ha tipo StringSet.elt = stringa ma si aspettava un'espressione di tipo 'una lista ". – Quyen

+1

C'è stato un piccolo errore alla riga 8, il primo argomento di iter è una lista di stringhe e non solo una stringa. Ho appena provato su [TryOCaml] (http://try.ocamlpro.com/) e ora funziona bene. – cago

Problemi correlati