F#递归函数:使列表项唯一

时间:2016-01-30 04:02:11

标签: list recursion f# tail-recursion

let rec isolate (l:'a list) = 
    match l with
    | [] -> []
    | x::xs ->
        if memberof(x,xs)
        then remove (x,l)
        else isolate xs

我已经创建了函数memberof和remove,唯一的问题是当第6行remove(x,l)执行时,它不会继续使用isolate(xs)继续搜索列表。< / p>

有没有办法说,

if x then f(x) and f(y)

3 个答案:

答案 0 :(得分:2)

当您使用F#immutable列表时,remove的结果需要存储在某处:

let rec isolate (l:'a list) = 
    match l with
    | [] -> []
    | x::xs ->
        if memberof(x,xs)
        then
            let xs = remove (x,l)
            isolate xs
        else isolate xs

回答更一般的问题:

let f _ = ()
let f' z = z

let x = true
let y = 42
let z = 3.141

if x then
    f y
    f' z |> ignore

这里需要ignore,因为在F#中没有语句,只有表达式,因此您可以将if x then f' z视为

if x then
    f' z
else
    ()

因此第一个分支也需要返回()

答案 1 :(得分:2)

除了CaringDev的回答。
你可以看看这个简单的解决方案 值得注意的是,这不是最快的方法。

let rec isolate (acc : 'a list) (l : 'a list) = 
  match l with
  | [] -> acc
  | head :: tail -> 
    if memberof (head, tail)
    then remove (head, tail) |> isolate (acc @ [head])
    else isolate (acc @ [head]) tail

let recursiveDistinct = isolate []
let uniqValues = recursiveDistinct [ 1; 1; 2; 3] //returns [1;2;3]

答案 2 :(得分:1)

let isolate list =
    let rec isolateInner searchList commonlist =
        match searchList with
        | x::xs ->
            if (memberof commonlist x) then
                isolateInner xs commonlist
            else
                let commonlist = (x :: commonlist)
                isolateInner xs commonlist
        | [] -> reverse commonlist
    isolateInner list []

这是对较大problem的答案的一部分。

请注意,这不使用remove。由于您必须传递原始列表中的每个项目并且列表是不可变的,因此最好创建一个新列表并仅将唯一项目添加到新列表中,然后返回新列表。