let undefined = ["string"; ""; "string"; "boolean";"";"innermost"]
我有一个列表,我想写一个函数返回一个没有重复和空字符串列表的列表。例如,上面的undefined
列表将返回:
["string"; "boolean"; "innermost"]
我写这个函数,它返回给我,没有重复,但我怎么能添加测试空字符串的条件。
let rec uniquify = function
| [] -> []
| x::xs -> x :: uniquify (List.filter ((<>) x) xs)
非常感谢
答案 0 :(得分:7)
您可以使用一组已经看过的字符串:
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
第一行定义字符串集的类型。
然后,uniquify调用一个辅助函数,在列表和集合中添加一个从未见过的字符串,或者只是丢弃该字符串。 acc
用于使迭代尾递归(因此,避免长列表上的堆栈溢出)。
使用这种方案更好,因为复杂性在O(N.log N)而不是N²。
答案 1 :(得分:5)
只需将结果传递给List.filter (fun s -> s <> "")
,然后删除空字符串。这是一种简单的,有组合的方式,你也可以破解你的功能,无声地放弃它
let rec uniquify = function
| [] -> []
| x::xs ->
(if x = "" then [] else [x]) @ uniquify (List.filter ((<>) x) xs)
请注意,您的函数是二次的,您可以通过先对列表进行排序,或者通过转换为集合并返回来提高复杂性。 Batteries具有为您执行此操作的功能。
let do_stuff list =
let open Batteries in
List.remove (List.sort_unique String.compare list) ""